一、interrupt()
interrupt方法用於中斷線程。調用該方法的線程的狀態爲將被置爲"中斷"狀態。
注意:線程中斷僅僅是置線程的中斷狀態位,不會中止線程。須要用戶本身去監視線程的狀態爲並作處理。支持線程中斷的方法(也就是線程中斷後會拋出interruptedException的方法)就是在監視線程的中斷狀態,一旦線程的中斷狀態被置爲「中斷狀態」,就會拋出中斷異常。
二、interrupted() 和 isInterrupted()html
首先看一下
API中該方法的實現:
1 |
public static boolean interrupted () { |
2 |
return currentThread().isInterrupted( true ); |
該方法就是直接調用當前線程的
isInterrupted(true)的方法。
而後
再來看一下API中 isInterrupted的實現:
1 |
public boolean isInterrupted () { |
2 |
return isInterrupted( false ); |
該方法卻直接調用當前線程的isInterrupted(false)的方法。java
所以這兩個方法有兩個主要區別:
- interrupted 是做用於當前線程,isInterrupted 是做用於調用該方法的線程對象所對應的線程。(線程對象對應的線程不必定是當前運行的線程。例如咱們能夠在A線程中去調用B線程對象的isInterrupted方法。)
- 這兩個方法最終都會調用同一個方法-----
isInterrupted( Boolean 參數
),
,只不過參數固定爲一個是true,一個是false; 注意: isInterrupted( Boolean 參數
)是isInterrupted(
)的重載方法。
因爲第二個區別主要體如今調用的方法的參數上,讓咱們來看一看這個參數是什麼含義
先來看一看被調用的方法 isInterrupted(boolean arg)
(Thread類中重載的方法)的定義:
1 |
private native boolean isInterrupted( boolean ClearInterrupted); |
原來這是一個本地方法,看不到源碼。不過不要緊,經過參數名ClearInterrupted咱們就能知道,這個參數表明是否要清除狀態位。
若是這個參數爲true,說明返回線程的狀態位後,要清掉原來的狀態位(恢復成原來狀況)。這個參數爲false,就是直接返回線程的狀態位。程序員
這兩個方法很好區分,只有當前線程才能清除本身的中斷位(對應interrupted()方法)jvm
因而寫了個例子想驗證一下:this
- public class Interrupt {
- public static void main(String[] args) throws Exception {
- Thread t = new Thread(new Worker());
- t.start();
-
- Thread.sleep(200);
- t.interrupt();
-
- System.out.println("Main thread stopped.");
- }
-
- public static class Worker implements Runnable {
- public void run() {
- System.out.println("Worker started.");
-
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- System.out.println("Worker IsInterrupted: " +
- Thread.currentThread().isInterrupted());
- }
-
- System.out.println("Worker stopped.");
- }
- }
- }
內容很簡答:主線程main啓動了一個子線程Worker,而後讓worker睡500ms,而main睡200ms,以後main調用worker線程的interrupt方法去中斷worker,worker被中斷後打印中斷的狀態。下面是執行結果:spa
- Worker started.
- Main thread stopped.
- Worker IsInterrupted: false
- Worker stopped.
Worker明明已經被中斷,而isInterrupted()方法居然返回了false,爲何呢?
.net
在stackoverflow上搜索了一圈以後,發現有網友提到:能夠查看拋出InterruptedException方法的JavaDoc(或源代碼),因而我查看了Thread.sleep方法的文檔,doc中是這樣描述這個InterruptedException異常的:線程
- InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
結論:interrupt方法是用於中斷線程的,調用該方法的線程的狀態將被置爲"中斷"狀態。注意:線程中斷僅僅是設置線程的中斷狀態位,不會中止線程。因此當一個線程處於中斷狀態時,若是再由wait、sleep以及jion三個方法引發的阻塞,那麼JVM會將線程的中斷標誌從新設置爲false,並拋出一個InterruptedException異常,而後開發人員能夠中斷狀態位「的本質做用-----就是程序員根據try-catch功能塊捕捉jvm拋出的InterruptedException異常來作各類處理,好比如何退出線程。總之interrupt的做用就是須要用戶本身去監視線程的狀態位並作處理。」code
同時能夠作這樣的理解:
Thread.currentThread().interrupt(); 這個用於清除中斷狀態,這樣下次調用Thread.interrupted()方法時就會一直返回爲true,由於中斷標誌已經被恢復了。
而調用isInterrupted()只是簡單的查詢中斷狀態,不會對狀態進行修改。xml
interrupt()是用來設置中斷狀態的。返回true說明中斷狀態被設置了而不是被清除了。咱們調用sleep、wait等此類可中斷(throw InterruptedException)方法時,一旦方法拋出InterruptedException,當前調用該方法的線程的中斷狀態就會被jvm自動清除了,就是說咱們調用該線程的isInterrupted 方法時是返回false。若是你想保持中斷狀態,能夠再次調用interrupt方法設置中斷狀態。這樣作的緣由是,java的中斷並非真正的中斷線程,而只設置標誌位(中斷位)來通知用戶。若是你捕獲到中斷異常,說明當前線程已經被中斷,不須要繼續保持中斷位。 interrupted是靜態方法,返回的是當前線程的中斷狀態。例如,若是當前線程被中斷(沒有拋出中斷異常,不然中斷狀態就會被清除),你調用interrupted方法,第一次會返回true。而後,當前線程的中斷狀態被方法內部清除了。第二次調用時就會返回false。若是你剛開始一直調用isInterrupted,則會一直返回true,除非中間線程的中斷狀態被其餘操做清除了。