關於interrupt

Thread類中有這麼幾個方法:html

  • public void interrupt()
  • public static boolean interrupted()
  • public boolean isInterrupted()

interrupt()

中斷線程。java

若是當前線程沒有中斷本身(這在任何狀況下都是容許的),則該線程的checkAccess方法就會被調用,這可能拋出SecurityException。程序員

若是線程在調用 Object 類的 wait()wait(long) 或 wait(long, int) 方法,或者該類的 join()join(long)join(long, int)sleep(long) 或 sleep(long, int) 方法過程當中受阻,則其中斷狀態將被清除,它還將收到一個 InterruptedExceptionredis

若是該線程在可中斷的通道上的 I/O 操做中受阻,則該通道將被關閉,該線程的中斷狀態將被設置而且該線程將收到一個 ClosedByInterruptExceptionapi

若是該線程在一個 Selector 中受阻,則該線程的中斷狀態將被設置,它將當即從選擇操做返回,並可能帶有一個非零值,就好像調用了選擇器的 wakeup 方法同樣。oracle

若是之前的條件都沒有保存,則該線程的中斷狀態將被設置。函數

中斷一個不處於活動狀態的線程不須要任何做用。性能

拋出:測試

SecurityException - 若是當前線程沒法修改該線程spa

 interrupted()

測試當前線程是否已經中斷。線程的中斷狀態 由該方法清除。換句話說,若是連續兩次調用該方法,則第二次調用將返回 false(在第一次調用已清除了其中斷狀態以後,且第二次調用檢驗完中斷狀態前,當前線程再次中斷的狀況除外)。

線程中斷被忽略,由於在中斷時不處於活動狀態的線程將由此返回 false 的方法反映出來。

返回:

若是當前線程已經中斷,則返回 true;不然返回 false

isInterrupted()

測試線程是否已經中斷。線程的中斷狀態 不受該方法的影響。

線程中斷被忽略,由於在中斷時不處於活動狀態的線程將由此返回 false 的方法反映出來。

探討interrupt

然而interrupt真的會幫你中止線程麼?答案是並不會。

一段簡單的代碼能夠以下圖所示:

public class Interrupt {
	
	public static void main(String[] args){
		
		Thread thread1 = new Thread(){
			public void run(){
				try {
					long time = System.currentTimeMillis();
					while(System.currentTimeMillis()-time<200){
						System.out.println("I am alive");
					}
					System.out.println("A1");
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println("B1");
				}
			}
		};
		thread1.start();
		thread1.interrupt();
        System.out.println(thread1.getName()+" "+thread1.isInterrupted());
}

代碼仍是會輸出I am alive

也就是說啓動的線程並無由於調用interrupt方法而終止,但是從isInterrupted方法返回的結果來看,線程是已經中斷了的;

根本緣由是由於沒有深入理解,JAVA API對這個方法的描述。咱們再回頭看一下:

若是線程在調用 Object 類的 wait()wait(long) 或 wait(long, int) 方法,或者該類的 join()join(long)join(long, int)sleep(long) 或 sleep(long, int) 方法過程當中受阻,則其中斷狀態將被清除,它還將收到一個 InterruptedException

該方法實際上只是設置了一箇中斷狀態,當該線程因爲上述緣由而受阻時,這個中斷狀態就起做用了。

也許咱們當設置了一個interrupt狀態之後,應該採用以下的響應機制,來進一步完成理論上應該達到的interrupt效果。

下面這段話引用自http://redisliu.blog.sohu.com/131647795.html

當外部線程對某線程調用了thread.interrupt()方法後,java語言的處理機制以下:    

若是該線程處在可中斷狀態下,(調用了xx.wait(),或者Selector.select(),Thread.sleep()等特定會發生阻塞的api),那麼該線程會當即被喚醒,同時會受到一個InterruptedException,同時,若是是阻塞在io上,對應的資源會被關閉。若是該線程接下來不執行「Thread.interrupted()方法(不是interrupt),那麼該線程處理任何io資源的時候,都會致使這些資源關閉。固然,解決的辦法就是調用一下interrupted(),不過這裏須要程序員自行根據代碼的邏輯來設定,根據本身的需求確認是否能夠直接忽略該中斷,仍是應該立刻退出。

若是該線程處在不可中斷狀態下,就是沒有調用上述api,那麼java只是設置一下該線程的interrupt狀態,其餘事情都不會發生,若是該線程以後會調用行數阻塞API,那到時候線程會馬會上跳出,並拋出InterruptedException,接下來的事情就跟第一種情況一致了。若是不會調用阻塞API,那麼這個線程就會一直執行下去。除非你就是要實現這樣的線程,通常高性能的代碼中確定會有wait(),yield()之類出讓cpu的函數,不會發生後者的狀況。

相關文章
相關標籤/搜索