當你的多線程代碼結構很復雜的時候很難找出bug的原因所在,此時我們可以使用getState()方法獲取該線程當前的狀態,通過觀察其狀態是阻塞了還是因為沒有啟動等原因導致的。
狀態 | 描述 |
---|---|
NEW | 安排了工作,還未開始行動 |
RUNNABLE | 可工作的,又可以分成正在工作中和即將開始工作 |
BLOCKED | 這幾個都表示排隊等著其他事情 |
WAITING | 這幾個都表示排隊等著其他事情 |
TIMED_WAITING | 這幾個都表示排隊等著其他事情 |
TERMINATED | 工作完成了 |
NEW
此狀態說明這個線程已經被創建了,但是沒有start()執行任務。
Thread t = new Thread(() -> {for (int i = 0; i < 1000_0000; i++) {}}, "狀態");System.out.println(t.getName() + ": " + t.getState());
RUNNABLE
這個狀態表明他已經被創建,但是還沒有執行完任務,在這個過程中都是RUNNABLE狀態。
Thread t = new Thread(() -> {for (int i = 0; i < 1000_0000; i++) {}}, "狀態");t.start();while (t.isAlive()) {System.out.println(t.getName() + ": " + t.getState());}
TERMINATED
已經執行完任務了,是線程結束的標志
Thread t = new Thread(() -> {for (int i = 0; i < 1000_0000; i++) {}}, "狀態");
t.start();
t.join();
System.out.println(t.getName() + ": " + t.getState());
WAITING
當他在使用wait,join,sleep方法等待的時候,并且方法沒有傳入參數,也就是死等的時候,需外部喚醒(如 notify()),處于此狀態。
Thread t1 = Thread.currentThread();Thread t = new Thread(() -> {try {t1.join();} catch (InterruptedException e) {throw new RuntimeException(e);}}, "狀態");t.start();Thread.sleep(10);System.out.println(t.getState());
TIMED_WAITING
當他在使用wait,join,sleep方法等待的時候,并且傳入參數會進入此狀態,超時后自動喚醒或外部提前喚醒,和WAITING的區別就是是否傳入參數的區別。
Thread t1 = Thread.currentThread();Thread t = new Thread(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}, "狀態");t.start();Thread.sleep(10);System.out.println(t.getState());
BLOCKED
因為鎖競爭導致的等待時,會進入此狀態,如果一直是此狀態可能是陷入了死鎖。
//這個案例是個死鎖。Object locker1 = new Object();Object locker2 = new Object();Thread t1 = new Thread(()->{synchronized (locker1) {try {Thread.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker2) {}}System.out.println("t1執行完畢");});Thread t2 = new Thread(()->{synchronized (locker2) {synchronized (locker1) {}}System.out.println("t2執行完畢");});t1.start();t2.start();Thread.sleep(100);System.out.println(t1.getState());