1. 線程生命週期:六種狀態
如下圖所示:
- NEW:創建線程之後還沒有執行start方法,此時線程處於NEW狀態
- RUNNABLE:執行start方法之後,處於RUNNABLE狀態,是可運行狀態。對應着操作系統READY(爲獲取到CPU)和RUNNING(獲取到CPU)兩種狀態,這兩種狀態在這裏都是可運行狀態。
- BLOCKED:
1. 當前線程等待另外一個線程釋放monitor鎖,以期待進入到synchronized修飾的方法或代碼塊,此時還沒有進入到該方法或代碼塊中,則進入到BLOCKED狀態;
2. 當從t1線程從WAITING狀態喚醒後,t1通常不能立即獲取到鎖,因爲另外一個喚醒t1線程的線程t2可能還沒執行完,那麼t1會先進入到BLOCKED狀態,搶到鎖後再進入到RUNNABLE狀態; - WAITING:必須在synchorized修飾的方法或代碼塊中執行了Object.wait()或Thread.join()後進入到WAITING狀態,等待其他線程去喚醒;
- TIME_WAITING:比WAITING狀態的方法多了時間參數,在超時後會被自動喚醒,如果超時之前執行notify()或notifyAll()可以提前喚醒
- TERMINATED:
1. run方法執行完畢;
2. 出現異常;
PS:BLOCKED狀態和WAITING狀態都是未獲得鎖,但是BLOCKED狀態是沒有執行wait方法時線程具有的狀態或者被其他線程執行了notify方法喚醒後(這個時候還沒有獲取到鎖)具有的狀態,而WAIT狀態時執行了wait方法後沒有被喚醒時具有的狀態。
以下是代碼演示:
public class NewRunnableTerminated implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new NewRunnableTerminated());
System.out.println(thread.getState());
thread.start();
System.out.println(thread.getState());
Thread.sleep(1000);
System.out.println(thread.getState());
}
}
NEW
RUNNABLE
TERMINATED
public class BlockedWaitingTimeWaiting implements Runnable {
@Override
public void run() {
syn();
}
private synchronized void syn(){
try {
Thread.sleep(2000);
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
BlockedWaitingTimeWaiting blockedWaitingTimeWaiting = new BlockedWaitingTimeWaiting();
Thread t1 = new Thread(blockedWaitingTimeWaiting);
t1.start();
Thread.sleep(500);//讓t1先啓動
Thread t2 = new Thread(blockedWaitingTimeWaiting);
t2.start();
System.out.println(t1.getState());//Thread.sleep(2000)使t1進入BLOCKED狀態
System.out.println(t2.getState());//t1沒有釋放鎖,是t1進入BLOCKED狀態
Thread.sleep(2000);
System.out.println(t1.getState());//wait()使t1進入到WAITING狀態
}
}
TIMED_WAITING
BLOCKED
WAITING
阻塞狀態:
- 一般地,Blocked、Waiting、TimedWaiting都稱爲阻塞狀態
- 不僅僅是Blocked