1. 程式人生 > >JAVA中五種執行緒狀態的分析

JAVA中五種執行緒狀態的分析

Thred執行緒狀態的分析
Java執行緒的生命週期中,存在幾種狀態。
新建狀態:
NEW: 執行緒建立之後,但是還沒有啟動(not yet started)。這時候它的狀態就是NEW

執行狀態:
RUNNABLE: 正在Java虛擬機器下跑任務的執行緒的狀態。在RUNNABLE狀態下的執行緒可能會處於等待狀態, 因為它正在等待一些系統資源的釋放,比如IO

阻塞狀態:
BLOCKED: 阻塞狀態,等待鎖的釋放,比如執行緒A進入了一個synchronized方法,執行緒B也想進入這個方法,但是這個方法的鎖已經被執行緒A獲取了,這個時候執行緒B就處於BLOCKED狀態
WAITING: 等待狀態,處於等待狀態的執行緒是由於執行了3個方法中的任意方法。
Object的wait方法,並且沒有使用timeout引數;
Thread的join方法,沒有使用timeout引數
LockSupport的park方法。 處於waiting狀態的執行緒會等待另外一個執行緒處理特殊的行為。
再舉個例子,如果一個執行緒呼叫了一個物件的wait方法,那麼這個執行緒就會處於waiting狀態直到另外一個執行緒呼叫這個物件的notify或者notifyAll方法後才會解除這個狀態

等待狀態:
TIMED_WAITING: 有等待時間的等待狀態,比如呼叫了以下幾個方法中的任意方法,並且指定了等待時間,執行緒就會處於這個狀態。

  1. Thread.sleep方法
  2. Object的wait方法,帶有時間
  3. Thread.join方法,帶有時間
  4. LockSupport的parkNanos方法,帶有時間
  5. LockSupport的parkUntil方法,帶有時間

死亡狀態:
TERMINATED: 執行緒中止的狀態,這個執行緒已經完整地執行了它的任務

如果只是簡單介紹上述的話,一半存在的都是面試的時候需要的,但如果想要深入理解,請看下方分析。
我們先說new新建狀態
NEW狀態比較簡單,例項化一個執行緒之後,並且這個執行緒沒有開始執行,這個時候的狀態就是NEW:

Thread thread = new Thread();
System.out.println(thread.getState()); // NEW

在新建完成之後,執行緒呼叫run方法進入執行狀態

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        for(int i = 0; i < Integer.MAX_VALUE; i ++) {
            System.out.println(i);
        }
    }
}, "run-Thred");
thread.start();

阻塞狀態中也就是
執行緒A和執行緒B都需要持有lock物件的鎖才能呼叫方法。如果執行緒A持有鎖,那麼執行緒B處於BLOCKED狀態;如果執行緒B持有鎖,那麼執行緒A處於BLOCKED狀態。例子中使用Thread.sleep方法主要是用於除錯方便

final Object lock = new Object();
Thread threadA = new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (lock) {
            System.out.println(Thread.currentThread().getName() + " invoke");
            try {
                Thread.sleep(20000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}, "執行緒a阻塞");
Thread threadB = new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (lock) {
            System.out.println(Thread.currentThread().getName() + " invoke");
            try {
                Thread.sleep(20000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}, "執行緒b阻塞");
threadA.start();
threadB.start();

等待狀態:
一般中我們最常用的就是wait方法,進入等待狀態,wait是Object的方法,還有就是另外的兩種Thread的join方法以及Conditon的await方法

final Object lock = new Object();
Thread threadA = new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (lock) {
            try {
                lock.wait();
                System.out.println("wait over");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}, "WAITING-Thread-A");
Thread threadB = new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (lock) {
            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.notifyAll();
        }
    }
}, "WAITING-Thread-B");
threadA.start();
threadB.start();

Thread的join方法

hread threadA = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread-A over");
    }
}, "WAITING-Thread-A");
threadA.start();
try {
    threadA.join();
} catch (InterruptedException e) {
    e.printStackTrace();
}

死亡狀態:
執行緒在執行完成之後,會結束生命週期

Thread threadA = new Thread();
threadA.start();
try {
    Thread.sleep(5000l);
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println(threadA.getState()); // TERMINATED