在java中一個線程能夠有如下四種狀態: java
1. 新建(new):當線程被建立時,它只會短暫地處於這種狀態。它已經分配了必需的系統資源,並執行了初始化。此刻線程已經有資格得到CPU時間了,以後調度器將把這個線程轉變爲可運行狀態或阻塞狀態。 ui
2. 就緒(Runnable):在這種狀態下,只要調度器把時間片分配給線程,線程就能夠運行。也就是說,在任意時刻,線程能夠運行也能夠不運行。只要調度器能分配時間片給線程,它就能運行;這不一樣於死亡和阻塞。 this
3. 阻塞(Blocked): 線程可以運行,但有某個條件阻止它的運行。當線程處於阻塞狀態時,調度器將忽略線程,不會分配線程任何CPU時間。直到線程從新進入就緒狀態,纔可能執行操做。 spa
4. 死亡(Dead): 處於死亡或終止狀態的線程將再也不可調度,而且不再會獲得CPU時間。任務死亡的一般方式是從run()方法返回,但任務的線程還能夠被中斷的。 線程
進入阻塞狀態的一些緣由: code
1. 經過sleep()使任務進入休眠狀態,任務在指定時間內不會運行。 對象
2. 經過wait()使線程掛起。直到線程獲得了notify()或notifyAll()消息,線程才進入就緒狀態。 資源
3. 任務在等待某個輸入\輸出完成。 get
4. 任務試圖在某個對象上調用其同步控制方法,可是對象鎖不可用,由於另外一線程已經得到了這個鎖。 同步
中斷:
Thread類包含interrupt()方法,所以能夠終止被阻塞的任務。
下面示例用Executor展現基本得interrupt()用法:
import java.io.IOException; import java.io.InputStream; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; class SleepBlocked implements Runnable{ public void run() { try{ TimeUnit.SECONDS.sleep(100); }catch(InterruptedException e){ System.out.println("InterruptedException"); } System.out.println("Exiting SleepBlocked.run()"); } } class IOBlocked implements Runnable{ private InputStream in; public IOBlocked (InputStream is){ in=is; } public void run() { try { System.out.println("waiting for read()"); in.read(); } catch (IOException e) { if(Thread.currentThread().isInterrupted()){ System.out.println("Interrupted from blocked I/O"); }else{ throw new RuntimeException(); } } System.out.println("Exiting IOBlocked.run()"); } } class SynchronizedBlocked implements Runnable{ public synchronized void f(){ while(true){//never releases lock Thread.yield(); } } public SynchronizedBlocked(){ new Thread(){ public void run(){ f();//lock acquired by this thread } }.start(); } public void run() { System.out.println("Trying to call f()"); f(); System.out.println("Exiting SynchronizedBlocked.run()"); } } public class Interrupting { private static ExecutorService exec = Executors.newCachedThreadPool(); static void test(Runnable r) throws InterruptedException{ Future<?> f = exec.submit(r); TimeUnit.MILLISECONDS.sleep(100); System.out.println("Interrupting "+r.getClass().getName()); f.cancel(true);//Interrupts if running System.out.println("Interrupt sent to "+r.getClass().getName()+"\n"); } public static void main(String args[]) throws Exception{ test(new SleepBlocked()); test(new IOBlocked(System.in)); test(new SynchronizedBlocked()); TimeUnit.SECONDS.sleep(3); System.out.println("Aborting with system.exit(0)"); System.exit(0); } }今後例子結果中能夠看到,SleepBlock是能夠中斷的,然後面兩種狀況是不能中斷的。