JAVA 中的線程狀態(tài)
java有6種線程狀態(tài)刻坊,java.lang.Thread.State枚舉中有對應狀態(tài)的描述
1 NEW:
創(chuàng)建后尚未啟動的線程處于這個狀態(tài)。這個線程還沒有被 start() 啟動成功。
2 RUNNABLE:
RUNNABLE狀態(tài)包括了操作系統(tǒng)線程狀態(tài)中的Running和Ready嚼沿,也就是處于此狀態(tài)的線程可能正在運行哨颂,也可能正在等待系統(tǒng)資源,如等待CPU為它分配時間片跌宛,如等待網(wǎng)絡IO讀取數(shù)據(jù)酗宋。
可運行線程的線程狀態(tài),等待CPU調度疆拘。由于在真正的系統(tǒng)中蜕猫,并不是開啟一個線程后,CPU就只為這一個線程服務哎迄,它必須使用許多調度算法來達到某種平衡回右,不過這個時候線程依然處于RUNNABLE狀態(tài)隆圆。
3 BLOCKED:
線程阻塞等待監(jiān)視器鎖定的線程狀態(tài)(處于synchronized同步代碼塊或方法中被阻塞)
4 WAITING:
等待線程的線程狀態(tài)。不帶超時的方式(Object.wait Thread.join LockSupport.park)
5 TIMED_WAITING:
具體指定等待時間的等待線程狀態(tài)楣黍。帶超時的方式(Object.wait Thread.join LockSupport.parkNanos LockSupport.parkUntil Thread.sleep)
6 TERMINATED:
終止線程的線程狀態(tài)匾灶。線程正常執(zhí)行完成或者出現(xiàn)異常。
線程六種狀態(tài)的切換關系
677054-20170401135927524-613651161.jpg
多線程切換代碼演示
新建 -> 運行 -> 終止
public static void main(String[] args) throws Exception{
// 第一種狀態(tài)切換 - 新建 -> 運行 -> 終止
System.out.println("#######第一種狀態(tài)切換 - 新建 -> 運行 -> 終止################################");
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread1當前狀態(tài):" + Thread.currentThread().getState().toString());
System.out.println("thread1 執(zhí)行了");
}
});
System.out.println("沒調用start方法租漂,thread1當前狀態(tài):" + thread1.getState().toString());
thread1.start();
Thread.sleep(2000L);
System.out.println("等待兩秒阶女,再看thread1當前狀態(tài):" + thread1.getState().toString());
// thread1.start(); TODO 注意,線程終止之后哩治,再進行調用秃踩,會拋出IllegalThreadStateException異常
}
新建 -> 運行 -> 等待 -> 運行 -> 終止(sleep方式)
public static void main(String[] args) throws Exception{
System.out.println("############第二種:新建 -> 運行 -> 等待 -> 運行 -> 終止(sleep方式)###########################");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {// 將線程2移動到等待狀態(tài),1500后自動喚醒
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread2當前狀態(tài):" + Thread.currentThread().getState().toString());
System.out.println("thread2 執(zhí)行了");
}
});
System.out.println("沒調用start方法业筏,thread2當前狀態(tài):" + thread2.getState().toString());
thread2.start();
System.out.println("調用start方法憔杨,thread2當前狀態(tài):" + thread2.getState().toString());
Thread.sleep(200L); // 等待200毫秒,再看狀態(tài)
System.out.println("等待200毫秒蒜胖,再看thread2當前狀態(tài):" + thread2.getState().toString());
Thread.sleep(3000L); // 再等待3秒消别,讓thread2執(zhí)行完畢,再看狀態(tài)
System.out.println("等待3秒台谢,再看thread2當前狀態(tài):" + thread2.getState().toString());
}
新建 -> 運行 -> 阻塞 -> 運行 -> 終止
public static void main(String[] args) throws Exception{
System.out.println("############第三種:新建 -> 運行 -> 阻塞 -> 運行 -> 終止###########################");
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (Hello.class) {
System.out.println("thread3當前狀態(tài):" + Thread.currentThread().getState().toString());
System.out.println("thread3 執(zhí)行了");
}
}
});
synchronized (Hello.class) {
System.out.println("沒調用start方法寻狂,thread3當前狀態(tài):" + thread3.getState().toString());
thread3.start();
System.out.println("調用start方法,thread3當前狀態(tài):" + thread3.getState().toString());
Thread.sleep(200L); // 等待200毫秒朋沮,再看狀態(tài)
System.out.println("等待200毫秒蛇券,再看thread3當前狀態(tài):" + thread3.getState().toString());
}
Thread.sleep(3000L); // 再等待3秒,讓thread3執(zhí)行完畢樊拓,再看狀態(tài)
System.out.println("等待3秒纠亚,讓thread3搶到鎖,再看thread3當前狀態(tài):" + thread3.getState().toString());
}