Java中interrupt()方法詳解附帶demo

  Thread.interrupt()的做用是通知線程應該中斷了,到底中斷仍是繼續運行,應該由被通知的線程本身處理。當對一個線程,調用 interrupt() 時,java

  1.若是線程處於被阻塞狀態(例如處於sleep, wait, join 等狀態),那麼線程將當即退出被阻塞狀態,並拋出一個InterruptedException異常。僅此而已。ide

  2.若是線程處於正常活動狀態,那麼會將該線程的中斷標誌設置爲 true,僅此而已。被設置中斷標誌的線程將繼續正常運行,不受影響。測試

  首先說第二條,線程正常執行,經過interrupt()方法將其中斷標誌設置爲true,在線程中使用Thread.interrupted()方法判斷當前線程是否被設置中斷標誌。this

public class StopThread implements Runnable { public static void main(String[] args) { StopThread stopThread = new StopThread(); Thread thread = new Thread(stopThread); thread.start(); System.out.println("thread starting..."); try { Thread.sleep(3000); thread.interrupt(); System.out.println("interrupt thread!"); Thread.sleep(3000); thread.join(); System.out.println("main stop!"); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { int i = 1; while (!Thread.interrupted()) i++; System.out.println("i=" + i); System.out.println("thread stop!"); } } 

  輸出:spa

thread starting... interrupt thread! i=-937646695 thread stop! main stop!

  這裏再說一下interrupted(),貼一下jdk1.8源碼的方法註釋,當調用這個方法會將中斷標誌重置,若是線程繼續執行,下一次調用這個方法返回爲false,除非再次調用interrupt()方法設置一次。簡單來講就是一次interrupt()只對應一次interrupted()的true狀態。線程

Tests whether the current thread has been interrupted. The <i>interrupted status</i> of the thread is cleared by this method. In other words, if this method were to be called twice in succession, the second call would return false 

  接下來研究下第一條,再寫一個簡單的demo,能夠看到線程正在sleep中,調用了interrupt()方法後,直接進入catch (InterruptedException e) {}中,而後繼續執行線程後續操做。因此在catch中寫中止線程的語句,便可達到目的。code

public class StopThread implements Runnable { public static void main(String[] args) { StopThread stopThread = new StopThread(); Thread thread = new Thread(stopThread); thread.start(); System.out.println("thread starting..."); try { Thread.sleep(1000); thread.interrupt(); System.out.println("interrupt thread!"); Thread.sleep(3000); thread.join(); System.out.println("main stop!"); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { System.out.println("throw InterruptedException!"); e.printStackTrace(); } System.out.println("thread stop!"); } }

  輸出blog

thread starting... interrupt thread!
throw InterruptedException! thread stop! java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at program.javaTest.threadtest.StopThread.run(StopThread.java:30) at java.lang.Thread.run(Thread.java:745) main stop!

  那麼還有個狀況,就是調用interrupt()時線程沒有處於阻塞,而後線程開始了sleep等三種方法阻塞,這時線程一樣會跳入catch (InterruptedException e) {}中,由於中斷標誌此時爲true。源碼

public class StopThread implements Runnable { public static void main(String[] args) { StopThread stopThread = new StopThread(); Thread thread = new Thread(stopThread); thread.start(); System.out.println("thread starting..."); try { thread.interrupt(); System.out.println("isInterrupted : " + thread.isInterrupted()); Thread.sleep(3000); thread.join(); System.out.println("main stop!"); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { long l = System.currentTimeMillis(); while (System.currentTimeMillis() - l < 5000); try { Thread.sleep(3000); } catch (InterruptedException e) { System.out.println("entry catch block!"); e.printStackTrace(); } System.out.println("thread stop!"); } }

  輸出it

thread starting... isInterrupted : true
entry catch block!
java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at program.javaTest.threadtest.StopThread.run(StopThread.java:30) at java.lang.Thread.run(Thread.java:745) thread stop! main stop!

  這個demo中多了一個thread.isInterrupted()方法,它也是用來測試線程中斷表示,不一樣的是,它是實例方法,因此返回的是實例thread的中斷標誌,這樣用來在線程外部管理線程的地方獲得線程中斷狀態;另外isInterrupted()方法不會重置中斷標誌。用這個方法時有另一個發現,當線程進入catch後,中斷標誌重置爲false!!!

P.S.interrupt()方法就講這麼多,它和信號變量一塊兒使用能夠達到很好的中斷線程目的。可是又有了新的問題,如今可以處理sleep等3個阻塞方法,若是線程阻塞在其餘方法上,好比IO中的read,該如何處理。這個以後會放在另一篇博文中詳細介紹。

相關文章
相關標籤/搜索