Java線程中斷interrupt的常用方法
前言
這裡主要探討中斷常用的三個方法:
- interrupt()。在一個線程中調用需要中斷現成的interrupt()方法,會對該線程發出信號,將中斷狀態標志為true
- isInterrupted()。判斷當前線程的中斷狀態。
- interrupted()。將線程的中斷狀態恢復。
主要使用的阻塞三個方法:
- Object#wait。放棄鎖+等待+重新獲取鎖
- Thread#join。【協作】等待某個線程執行完畢
- Thread#sleep。靜態方法,線程休眠並讓出CPU時間片
==註意:interrupt()不能中斷在運行中的線程,它隻能改變中斷狀態而已。實際完成的是讓受阻塞的線程退出阻塞狀態。==
確切的說:是被三種方法之一阻塞時,調用該線程的interrupt()方法,那麼線程將拋出一個個InterruptedException中斷異常,從而提早地終結被阻塞狀態。
示例說明
public class Runner3 implements Runnable { @Override public void run() { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("我進入中斷瞭,但我還在跑"); } else { System.out.println("我沒有進入中斷"); } } } public static void main(String[] args) { Runner3 runner3 = new Runner3(); Thread thread3 = new Thread(runner3); thread3.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } thread3.interrupt(); } }
輸出結果大致如下:
我沒有進入中斷
我沒有進入中斷
我進入中斷瞭,但我還在跑
我進入中斷瞭,但我還在跑
我進入中斷瞭,但我還在跑
…
這裡看到,執行interrupt()後,對線程執行中斷後依然在執行,線程依然在運行。
我們調整一下run方法
public void run() { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("我進入中斷瞭,但我還在跑"); Thread.interrupted();//重置狀態 } else { System.out.println("我沒有進入中斷"); } } }
輸出結果如下:
我沒有進入中斷
我沒有進入中斷
我進入中斷瞭,但我還在跑
我沒有進入中斷
我沒有進入中斷
…
這裡看到中斷的狀態重置瞭,那麼我們如何去應用這個中斷狀態呢?
註意事項
- 當線程A執行到wait(),sleep(),join()時,拋出InterruptedException後,中斷狀態已經被系統復位瞭,線程A調用Thread.interrupted()返回的是false。
- 如果線程被調用瞭interrupt(),此時該線程並不在阻塞狀態時,下次執行wait(),sleep(),join()時,一樣會拋出InterruptedException,當然拋出後該線程的中斷狀態也會被系統復位。
案例1
public class Runner3 implements Runnable { @Override public void run() { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("我進入中斷瞭,但我還在跑"); // try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("2"+Thread.currentThread().isInterrupted()); //輸出false } } else { System.out.println("我沒有進入中斷"); } } } public static void main(String[] args) { Runner3 runner3 = new Runner3(); Thread thread3 = new Thread(runner3); thread3.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } thread3.interrupt(); } }
執行上面的代碼,我們可以看到在拋出異常後,Thread.currentThread().isInterrupted()輸出為false,證明線程的中斷狀態已經復位瞭。
另外因為我們是先執行瞭interrupt()然後再進入睡眠狀態,但是依然拋出瞭異常。
Object#wait 和 Thread.sleep 差異在哪裡
因為Object#wait方法會阻塞線程,所以當我們執行interrupt時,會拋出InterruptedException異常。
那麼Object#wait方法阻塞線程會導致的差異在哪裡?
==最主要的差別在於sleep方法沒有釋放鎖,而wait方法釋放瞭鎖,使得其它線程可以使用同步控制塊或者方法。==
總結
- 調用interrupt方法,會改變中斷狀態,但不會影響線程的運行狀態。
- 當執行瞭interrupt方法改變中斷狀態後,線程若執行Object#wait,Thread#sleep和Thread#join都會拋出InterruptedException異常,然後復位中斷狀態
- 當執行瞭interrupt方法改變中斷狀態後,線程未阻塞,且將要執行Object#wait,Thread#sleep和Thread#join阻塞線程時,都會拋出InterruptedException異常,復位中斷狀態。
到此這篇關於Java線程中斷interrupt的常用方法的文章就介紹到這瞭,更多相關Java線程中斷interrupt內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- java中斷機制實例講解
- 一篇文章掌握Java Thread的類及其常見方法
- 淺談Thread.sleep()為什麼要拋出中斷異常
- Java多線程Thread類的使用及註意事項
- 詳解Java 線程中斷