java多線程學習總結之二:線程狀態的轉換

在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是能夠中斷的,然後面兩種狀況是不能中斷的。
相關文章
相關標籤/搜索