1、線程的狀態html
線程能夠阻塞於四種狀態:java
一、當線程執行Thread.sleep()時,它一直阻塞到指定的毫秒時間以後,或者阻塞被另外一個線程打斷;linux
二、當線程碰到一條wait()語句時,它會一直阻塞到接到通知notify()、被中斷、通過了指定時間爲止(如有超時值的話)jvm
三、線程阻塞與不一樣I/O的方式函數
3.1. 常見的一種方式是InputStream的read()方法,該方法一直阻塞到從流中讀取一個字節的數據爲止,它能夠無限阻塞,所以不能指定超時時間;post
3.2 java.nio
中的非阻塞 I/O 類也不支持可中斷 I/O,可是一樣能夠經過關閉通道或者請求 Selector
上的喚醒來取消阻塞操做this
四、線程也能夠阻塞等待獲取某個對象鎖的排他性訪問權限(即等待得到synchronized語句必須的鎖時阻塞)。url
注意,並不是全部的阻塞狀態都是可中斷的,以上阻塞狀態的前兩種能夠被中斷,後兩種不會對中斷作出反應spa
wait vs blocked操作系統
synchronized(Obj) { Obj.wait(); }
t1先進,最後在Obj.wait()下卡住,這時java管t1的狀態waitting狀態
t2後進,直接在第一行就卡住了,這時java叫t2爲blocked狀態。
請注意,blocked是過去分詞,意味着他是被卡住的。由於這段代碼只讓一條線程運行。同時,jvm是知道怎麼結束blocked的,只要別的線程退出這段代碼,他就會自動讓你進去。也就是說別的線程無需喚醒你,由jvm自動來幹。
而waiiting是說我調用wait()等函數,主動卡住本身(我在等一個白富美),請jvm在知足某種條件後(白富美髮消息讓咱們晚上見),好比另條線程調用了notify()後,把我喚醒。這個喚醒的責任在於別的線程(白富美)明確的調用一些喚醒函數。
作這樣的區分,是jvm出於管理的須要,作了這種區分,好比兩個緣由的線程放兩個隊列裏管理,若是別的線程運行出了synchronized這段代碼,我只須要去blocked隊列,放個出來。而某人調用了notify(),我只須要去waitting隊列裏取個出來。
P.S. 從linux內核來看,這些線程都是等待狀態,沒區別,區別只在於java的管理須要。一般咱們在系統級別說線程的blocked,是說線程操做io,被暫停了,這種線程由linux內核來喚醒(io設備報告數據來了,內核把block的線程放進可運行的進程隊列,
2、中斷某個線程
當對一個線程,調用 interrupt() 時
① 若是線程處於正常活動狀態,那麼會將該線程的中斷標誌設置爲 true。被設置中斷標誌的線程將繼續正常運行,不受影響。
② 若是線程處於被阻塞狀態(sleep, wait, join 等狀態),那麼線程將當即退出被阻塞狀態,並拋出一個InterruptedException
interrupt() 並不能真正的中斷線程,須要被調用的線程本身進行配合才行
① 在正常運行任務時,常常檢查本線程的中斷標誌位,若是被設置了中斷標誌就自行中止線程
② 在調用阻塞方法時正確處理InterruptedException異常
1。當線程沒有處於阻塞狀態,經過改變標誌量,可讓線程中止。
1 public class Example01 extends Thread { 2 boolean stop=false; 3 public static void main( String args[] ) throws Exception { 4 Example01 thread = new Example01(); 5 thread.start(); 6 Thread.sleep(1000); 7 thread.interrupt(); //線程不會中止 8 // thread.stop = true; //線程會中止 9 } 10 public void run() { 11 while(!stop){ 12 System.out.println( "Thread is running..." ); 13 14 } 15 System.out.println("Thread exiting..." ); 16 } 17 }
2。當線程處於阻塞狀態,調用interrupt()方法。
If this thread is blocked in an invocation of the wait()
methods of the Object
class, or of the join()
, , sleep(long)
methods of
Thread class, then its interrupt status will be cleared and it will receive an InterruptedException
.
1 public class Example01 extends Thread { 2 boolean stop=false; 3 public static void main( String args[] ) throws Exception { 4 Example01 thread = new Example01(); 5 thread.start(); 6 Thread.sleep(1000); 7 thread.interrupt(); 8 9 } 10 public void run() { 11 System.out.println("-------sleeping"); 12 try { 13 Thread.sleep(2000); 14 } catch (InterruptedException e) { 15 e.printStackTrace(); 16 } 17 System.out.println("-------caclulating"); 18 double d = 0; 19 for(int i=1; i<2500000; i++){ 20 d += Math.E/d; 21 } 22 System.out.println("-------finish caclulating"); 23 24 } 25 }
3.當線程處於阻塞狀態,能夠中斷等待的資源,如I/O, Socket
參考:
self: AQS 與 LockSupport