Java_多線程之interrupt()

轉載大佬的https://www.cnblogs.com/skywang12345/p/3479949.html、

特別好。

補充:又發現了另一位大佬的博客https://www.cnblogs.com/death00/p/11585028.html

自己的一點理解:

最終作用是中斷線程。

  • Thread.interrupt(),設置當前中斷標記爲true
  • Thread對象.isInterrupted(),檢測當前線程對象的中斷標記
  • Thread.interrupted(),檢測當前的中斷標記,然後重置中斷標記爲false
    因此interrupt中斷機制並不是真正的將當前線程中斷,而是一箇中斷標記的變化

1.首先API:

interrupt()的作用是中斷本線程。
本線程中斷自己是被允許的;其它線程調用本線程的interrupt()方法時,會通過checkAccess()檢查權限。這有可能拋出SecurityException異常。
如果本線程是處於阻塞狀態:調用線程的wait(), wait(long)或wait(long, int)會讓它進入等待(阻塞)狀態,或者調用線程的join(), join(long), join(long, int), sleep(long), sleep(long, int)也會讓它進入阻塞狀態。若線程在阻塞狀態時,調用了它的interrupt()方法,那麼它的“中斷狀態”會被清除並且會收到一個InterruptedException異常。例如,線程通過wait()進入阻塞狀態,此時通過interrupt()中斷該線程;調用interrupt()會立即將線程的中斷標記設爲“true”,但是由於線程處於阻塞狀態,所以該“中斷標記”會立即被清除爲“false”,同時,會產生一個InterruptedException的異常。
如果線程被阻塞在一個Selector選擇器中,那麼通過interrupt()中斷它時;線程的中斷標記會被設置爲true,並且它會立即從選擇操作中返回。
如果不屬於前面所說的情況,那麼通過interrupt()中斷線程時,它的中斷標記會被設置爲“true”。
中斷一個“已終止的線程”不會產生任何操作。

interrupt()只是發出中斷信號,並不能立刻結束線程。

所以對於一個線程處於阻塞狀態,通過interrupt()中斷,剛開始爲立即將中斷標記設爲"true",但由於拋異常它的中斷標記最終會被設置爲“false”。同時,會產生一個InterruptedException的異常。通過捕獲這個異常進行結束

其次對於一個運行狀態的線程,那麼通過interrupt()中斷線程時,它的中斷標記會被設置爲“true”。所以配合Thread對象.isInterrupted()進行結束

即可。

總而言之結合兩種情況,最終要實現中斷所有線程可以在這樣:

@Override
public void run() {
    try {
        // 1. isInterrupted()保證,只要中斷標記爲true就終止線程。
        while (!isInterrupted()) {
            // 執行任務...
        }
    } catch (InterruptedException ie) {  
        // 2. InterruptedException異常保證,當InterruptedException異常產生時,線程被終止。
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章