2、interrupted() 和 isInterrupted()
1 |
public static boolean interrupted
() { |
2 |
return currentThread().isInterrupted( true ); |
3 |
} |
1 |
public boolean isInterrupted
() { |
2 |
return isInterrupted( false ); |
3 |
} |
該方法卻直接調用當前線程的isInterrupted(false)的方法。
- interrupted 是作用於當前線程,isInterrupted 是作用於調用該方法的線程對象所對應的線程。(線程對象對應的線程不一定是當前運行的線程。例如我們可以在A線程中去調用B線程對象的isInterrupted方法。)
- 這兩個方法最終都會調用同一個方法-----
isInterrupted( Boolean 參數
),
,只不過參數固定爲一個是true,一個是false; 注意:isInterrupted( Boolean 參數
)是
isInterrupted(
)的重載方法。
1 |
private native boolean isInterrupted( boolean ClearInterrupted); |
如果這個參數爲true,說明返回線程的狀態位後,要清掉原來的狀態位(恢復成原來情況)。這個參數爲false,就是直接返回線程的狀態位。
這兩個方法很好區分,只有當前線程才能清除自己的中斷位(對應interrupted()方法)
於是寫了個例子想驗證一下:
- 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被中斷後打印中斷的狀態。下面是執行結果:
Worker明明已經被中斷,而isInterrupted()方法竟然返回了false,爲什麼呢?
在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的作用就是需要用戶自己去監視線程的狀態位並做處理。”
同時可以做這樣的理解:
Thread.currentThread().interrupt(); 這個用於清除中斷狀態,這樣下次調用Thread.interrupted()方法時就會一直返回爲true,因爲中斷標誌已經被恢復了。
而調用isInterrupted()只是簡單的查詢中斷狀態,不會對狀態進行修改。
interrupted是靜態方法,返回的是當前線程的中斷狀態。例如,如果當前線程被中斷(沒有拋出中斷異常,否則中斷狀態就會被清除),你調用interrupted方法,第一次會返回true。然後,當前線程的中斷狀態被方法內部清除了。第二次調用時就會返回false。如果你剛開始一直調用isInterrupted,則會一直返回true,除非中間線程的中斷狀態被其他操作清除了。