在Thread
類中,提供了stop()
,suspend()
和resume()
方法,這三個方法分別是用來結束,暫停,恢復線程. 可是都已經被標記爲@Deprecated廢棄了. 由於一個線程不該該由其餘線程來結束,他應該收到別人的通知,而後本身在合適的位置結束,若是不合理的結束,會致使不少意外的結果,好比臨界區還沒徹底操做完,提早釋放鎖,可是部分狀態已經改變,還有沒有作一些清理操做等等.java
基於上面的理由,Java提供了新的中斷機制(interrupt),其餘線程調用想要終止線程的interrupt()
方法. 這個時候線程會根據本身的狀態作出響應:ide
InterruptedException
異常.public static void main(String[] args) { Thread thread = new Thread() { @Override public void run() { try { // 被調線程阻塞本身30s sleep(30000); } catch (InterruptedException e) { e.printStackTrace(); } } }; try { // 啓動線程 thread.start(); // 主線程阻塞本身3秒 TimeUnit.SECONDS.sleep(3); // 中斷線程 thread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } // ↓ out ↓ // java.lang.InterruptedException: sleep interrupted // ...
被調用線程不處於阻塞的時候,須要調用方法來監控標誌.spa
public static void main(String[] args) { Thread thread = new Thread() { @Override public void run() { while (!Thread.interrupted()) { System.out.println("我還穩得住..."); } } }; try { thread.start(); TimeUnit.SECONDS.sleep(3); thread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } // ↓ out ↓ // 我能穩得住 // ...
該程序會在檢測interrupt標誌,若是發現interrupt標誌設置爲true,則會結束本身.線程
區別: 是否會清除interrupt標誌. isInterrupt()方法不會改變標誌,而interrupted()方法會在檢測的同時,若是發現標誌爲true,則會返回true,而後把標誌置爲false.code
public static void main(String[] args) { Thread thread = new Thread() { @Override public void run() { while (!Thread.interrupted()) { System.out.println("我還穩得住..."); } // ⚠️⚠️添加下面代碼⚠️⚠️ System.out.println(Thread.interrupted()); } }; try { thread.start(); TimeUnit.SECONDS.sleep(3); thread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } // ↓ out ↓ // 我還穩得住... // ...(省略) // false
上面實例說明Thread.interrupted()方法會在標誌爲true的狀況下修改interrupted的標誌.rem
public static void main(String[] args) { Thread thread = new Thread() { @Override public void run() { // ⚠️⚠️修改方法⚠️⚠️ while (!isInterrupted()) { System.out.println("我還穩得住..."); } System.out.println(Thread.interrupted()); } }; try { thread.start(); TimeUnit.SECONDS.sleep(3); thread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } // ↓ out ↓ // 我還穩得住... // ...(省略) // true
經過觀察源碼能夠看出interrupted方法最後會調用isInterrupted(true)方法,而傳入的參數表明是否清除標誌位. 能夠看到isInterrupted(boolean)是一個本地方法,最終會經過C/C++來執行. 而isInterrupted()最後傳入的參數爲false,說明不清除標誌位.源碼