執行緒執行過程中的狀態
阿新 • • 發佈:2021-06-10
1 執行緒執行過程中的狀態
- new 初始化狀態
- runnalbe 可執行/執行狀態
- blocked 阻塞狀態
- waiting 等待狀態,無時間限制
- timed_waiting 超時等待,有時間限制
- terminated 終止狀態
1.1 各個狀態介紹
1.1.1 new 初始化狀態
實現Runnable介面和繼承Thread可以得到一個執行緒類,從而可以new一個例項出來,執行緒進入初始化。
public class ThreadTest extends Thread{ private String name; public ThreadTest(String name){this.name = name} public void run(){ for(int i = 1; i < 11; i++){ System.out.println(Thread.currentThread().getName() + " Thread " + i); } } public static void main(String[] args){ ThreadTest t1 = new ThreadTest("thread1"); ThreadTest t2 = new ThreadTest("thread2"); ThreadTest t3 = new ThreadTest("thread3"); t1.start(); t2.start(); t3.start(); } }
public class TestRunnable implements Runnable{ public void run(){ for(int i = 1; i < 11; i++){ System.out.println(Thread.currentThread().getName() + " Thread " + i); } } public static void main(String[] args){ ThreadTest t1 = new ThreadTest("thread1"); ThreadTest t2 = new ThreadTest("thread2"); ThreadTest t3 = new ThreadTest("thread3"); t1.start(); t2.start(); t3.start(); } }
1.1.2 Runnable 就緒,執行中的狀態
- 就緒狀態只是說你自己在執行,排程程式沒有選到你,你就永遠是就緒狀態。
- 呼叫執行緒的start()方法,執行緒進入就緒狀態
- 當前執行緒slee()方法結束,其他程序join()結束,等待使用者輸入完畢,某個執行緒拿到物件鎖,這些執行緒也將進入就緒狀態。
- 當前執行緒時間片用完了,呼叫當前執行緒的yield()方法,當前執行緒進入就緒狀態。
- 鎖池裡的執行緒拿到物件鎖後,進入就緒狀態。
1.1.3 Running 執行中狀態
執行緒排程程式可以從執行池中選擇一個執行緒作為當前執行緒時,執行緒進入執行狀態。
這也是執行緒進入執行狀態的唯一方式。
1.1.4 Blocked 阻塞狀態
阻塞狀態是指執行緒阻塞在進入synchronized關鍵字修飾的方法或程式碼塊(獲取鎖)之前的狀態。
1.1.5 Waiting 等待狀態
呼叫sleep()或者wait()方法後,執行緒處於waiting狀態,等待被喚醒。
1.1.6 timed_waiting 等待超時狀態
呼叫sleep()或者wait()方法後,執行緒處於timed_waiting狀態,等待被喚醒,或者超時被自動喚醒。
1.1.7 treminated 終止狀態
- 當前執行緒的run方法完成時,或者主執行緒的main方法完成時,我們就認為他終止了。這個物件也許是活的,但是他已經不是一個獨立執行的執行緒。執行緒一旦停止,就不能復生。
- 在一個終止執行緒上呼叫start方法,會丟擲java.long.IllegalThreadStateException異常
1.2 執行緒之間狀態的切換
1.2.1 new -> runnable
- 實現runnable介面,或者整合thread類,可以獲得一個執行緒類,建立這個類的例項物件,就是new
- new狀態的執行緒不會被作業系統排程,也不會被執行
- 呼叫的這個執行緒的start方法,將new狀態轉換成runnable狀態
1.2.2 runnable -> block -> runnable
- runnable執行緒獲得cpu執行時間,執行run方法,進入running狀態
- running執行緒進入synchronized同步塊,可能進行同步阻塞或IO阻塞,進入blocked狀態
- block執行緒同步synchronized同步塊,可能進行同步塊釋放或IO完成,進入runnable狀態
只有當執行緒等待synchronized的隱形鎖時,執行緒才會從runnable向blocked狀態轉換。
被synchronizded關鍵字修飾的方法、程式碼,在同一時刻,只允許一個執行緒執行。
所以在這種情況下,等待的執行緒就會從runnable變為block,當等待的執行緒獲得synchronized隱式鎖時,就會從block狀態轉到如runnable。
1.2.3 runnable -> running -> waiting -> runnable
- 有三種情況會觸發執行緒從runnable轉到waiting
- 獲得synchronized的執行緒呼叫Object.wait()
- 呼叫執行緒同步Thread.join方法
- 執行緒A在runnable。得到cpu執行時間後,變為running
- 執行緒B呼叫join方法,插隊。
- 執行緒A進入主動等待狀態,變為waiting
- 執行緒B執行完畢了以後,執行緒A變為runnable
- 呼叫LockSupport.park方法。Java併發包中的鎖,都是基於LockSupport物件實現的。
- 呼叫LockSupport.park(),執行緒會阻塞,從running變為waiting
- 呼叫LockSupport.unpark(),執行緒被喚醒,從waiting變為runnable
1.2.4 runnable -> timed_waiting
- 有五種情況會出發執行緒從runnable轉到timed_waiting
- 呼叫帶超時引數的Thread.sleep(long millis)
- 獲得synchronized執行緒,呼叫帶引數的OBject.wait(long deadline)方法
- 呼叫帶引數的LockSupport.parkNanos(Object blocker, long deadline)
- 呼叫帶超時引數的LocalSupport.parkUntil(long deadline)
1.2.5 runnable -> terminated
這是一個自動的過程,一個執行緒正常執行完畢以後,就會變成terminated
如果執行時,有異常丟擲,也會終止程序
或者呼叫interrupt方法,中斷執行緒。