簡體   English   中英

停止,中斷,暫停和恢復java線程

[英]Stop, interrupt, suspend and resume a java thread

我開始閱讀有關如何安全地停止,中斷,暫停和恢復java線程的問題,我在oracle文檔中找到了以下解決方案:

1-如何安全地停止線程:

private volatile Thread blinker;

public void stop() {
    blinker = null;
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (blinker == thisThread) {
        try {
            Thread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

-要停止一個線程,我可以使用boolean變量而不是volatile Thread ,但為什么Oracle堅持要對啟動的線程影響null? 在這樣做的背后是否有任何秘密(例如解放使用終結器分配的資源)?

2-如何中斷等待很長時間的線程:

public void stop() {
    Thread moribund = waiter;
    waiter = null;
    moribund.interrupt();
}

-為什么我要創建新的變量moribund而不是直接使用waiter.interrupt()

3-如何暫停和恢復線程:

private volatile boolean threadSuspended;

public void run() {
    while (true) {
        try {
            Thread.sleep(interval);

            if (threadSuspended) {
                synchronized(this) {
                    while (threadSuspended)
                        wait();
                }
            }
        } catch (InterruptedException e){
        }
        repaint();
    }
}

public synchronized void mousePressed(MouseEvent e) {
    e.consume();

    threadSuspended = !threadSuspended;

    if (!threadSuspended)
        notify();
}

-為什么內部run方法他們添加了循環while (threadSuspended)因為我不明白添加它的目的是什么,我的代碼可以編譯並在沒有它的情況下正確運行(具有相同的輸出結果)。

來源鏈接http://docs.oracle.com/javase/8/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

1.使用本地Thread變量可防止其他線程調用對象的run()方法。 只有此對象實例表示的線程才能使用run()方法。 它一般是不好的做法,調用run()一個方法Thread從不同的手動Thread ,但絕對有可能。

2.這一點需要在第1點的上下文中解釋。這部分還考慮了interval很長的情況,並且線程需要盡快停止。
您當然需要使引用無效,否則第1部分中的代碼將繼續循環。 但是考慮一下如果將stop方法簡化為:

public void stop() {
    waiter.interrupt();
    waiter = null;    
}

由於這是從另一個線程執行的,因此它可以以任何方式與run()方法交織在一起。 例如,threadA調用stop()來停止run() threadB:

  1. threadB:睡眠(間隔)
  2. threadA:waiter.interrupt()
  3. threadB:捕獲InterruptedException
  4. threadB:調用重繪
  5. threadB:循環時輸入next
  6. threadB:進入睡眠(間隔)
  7. threadA:服務員== null

在這種情況下,threadB不是立即停止,而是進行另一個休眠循環,這使得stop a thread that waits for long periods的設置任務失敗。 在給定的實現中,您首先使null,然后中斷,這會阻止這種行為。

3.簡而言之:因為另一個線程可能已通知您的代碼,而沒有設置正確的標志。 notify()的一般合同是呼叫是無害的(但是無用的呼叫顯然會消耗一些資源)。 所有線程都應該能夠應對虛假的喚醒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM