java---interrupt、interrupted和isInterrupted的區別

一、interrupt() 
interrupt方法用於中斷線程。調用該方法的線程的狀態爲將被置爲"中斷"狀態。
注意:線程中斷僅僅是置線程的中斷狀態位,不會中止線程。須要用戶本身去監視線程的狀態爲並作處理。支持線程中斷的方法(也就是線程中斷後會拋出interruptedException的方法)就是在監視線程的中斷狀態,一旦線程的中斷狀態被置爲「中斷狀態」,就會拋出中斷異常。

 

二、interrupted() 和 isInterrupted()html

首先看一下 API中該方法的實現:
1 public static boolean interrupted () {
2      return currentThread().isInterrupted(true);
3 }
該方法就是直接調用當前線程的 isInterrupted(true)的方法。
而後 再來看一下API中 isInterrupted的實現:
1 public boolean isInterrupted () {
2      return isInterrupted( false);
3 }

該方法卻直接調用當前線程的isInterrupted(false)的方法。java

所以這兩個方法有兩個主要區別:
  1. interrupted 是做用於當前線程,isInterrupted 是做用於調用該方法的線程對象所對應的線程。(線程對象對應的線程不必定是當前運行的線程。例如咱們能夠在A線程中去調用B線程對象的isInterrupted方法。)
  2. 這兩個方法最終都會調用同一個方法-----isInterrupted( Boolean 參數),,只不過參數固定爲一個是true,一個是false;               注意: isInterrupted( Boolean 參數)是isInterrupted( )的重載方法。
 
因爲第二個區別主要體如今調用的方法的參數上,讓咱們來看一看這個參數是什麼含義
 
先來看一看被調用的方法 isInterrupted(boolean arg) (Thread類中重載的方法)的定義:
1 private native boolean isInterrupted( boolean ClearInterrupted);
原來這是一個本地方法,看不到源碼。不過不要緊,經過參數名ClearInterrupted咱們就能知道,這個參數表明是否要清除狀態位。

若是這個參數爲true,說明返回線程的狀態位後,要清掉原來的狀態位(恢復成原來狀況)。這個參數爲false,就是直接返回線程的狀態位。程序員

這兩個方法很好區分,只有當前線程才能清除本身的中斷位(對應interrupted()方法)jvm

 

因而寫了個例子想驗證一下:this

 

[java]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. public class Interrupt {  
  2.     public static void main(String[] args) throws Exception {  
  3.         Thread t = new Thread(new Worker());  
  4.         t.start();  
  5.           
  6.         Thread.sleep(200);  
  7.         t.interrupt();  
  8.           
  9.         System.out.println("Main thread stopped.");  
  10.     }  
  11.       
  12.     public static class Worker implements Runnable {  
  13.         public void run() {  
  14.             System.out.println("Worker started.");  
  15.               
  16.             try {  
  17.                 Thread.sleep(500);  
  18.             } catch (InterruptedException e) {  
  19.                 System.out.println("Worker IsInterrupted: " +   
  20.                         Thread.currentThread().isInterrupted());  
  21.             }  
  22.               
  23.             System.out.println("Worker stopped.");  
  24.         }  
  25.     }  
  26. }  

內容很簡答:主線程main啓動了一個子線程Worker,而後讓worker睡500ms,而main睡200ms,以後main調用worker線程的interrupt方法去中斷worker,worker被中斷後打印中斷的狀態。下面是執行結果:spa

 

 

[vb]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. Worker started.  
  2. Main thread stopped.  
  3. Worker IsInterrupted: false  
  4. Worker stopped.  

Worker明明已經被中斷,而isInterrupted()方法居然返回了false,爲何呢?

.net

在stackoverflow上搜索了一圈以後,發現有網友提到:能夠查看拋出InterruptedException方法的JavaDoc(或源代碼),因而我查看了Thread.sleep方法的文檔,doc中是這樣描述這個InterruptedException異常的:線程

 

[html]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片
  1. InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.  



 

[html]  view plain  copy
 
 在CODE上查看代碼片派生到個人代碼片

結論: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,除非中間線程的中斷狀態被其餘操做清除了。
相關文章
相關標籤/搜索