Java中線程的狀態(tài)一共有6種:
image.png
圖片來源于網(wǎng)絡(luò)
- 新建(New):新建一個線程對象囱嫩,但沒有調(diào)用start()方法嫂侍;從New狀態(tài)出發(fā)后儿捧,線程就不會回到New狀態(tài)
- 運行(Runnable):Java中將正在運行(Running)和就緒(Ready)統(tǒng)稱為運行(Runnable)。線程創(chuàng)建后挑宠,其他線程若調(diào)用了該線程的start()方法菲盾,則該線程進入就緒(Ready)狀態(tài),等待獲取CPU的時間片痹栖。而該線程獲得CPU時間片后則轉(zhuǎn)變?yōu)檎谶\行(Running)亿汞。
就緒(Ready)狀態(tài):當(dāng)沒有分配CPU時間片時瞭空,線程永遠處于就緒(Ready)狀態(tài)揪阿;當(dāng)調(diào)用了start()方法時疗我,線程就進入就緒(Ready)狀態(tài);當(dāng)線程的sleep()方法結(jié)束南捂,或其他線程join()結(jié)束吴裤,等待用戶輸入完畢又或者某個線程拿到對象鎖后,這些線程也會進入就緒狀態(tài);當(dāng)前線程的時間片使用完后溺健,調(diào)用當(dāng)前線程的yield()方法麦牺,當(dāng)前線程也會進入就緒狀態(tài),當(dāng)阻塞狀態(tài)中等待鎖的線程拿到鎖后鞭缭,進入就緒狀態(tài)剖膳。
運行(Running)狀態(tài):CPU從線程池中選擇一個線程,從而使得該線程處于運行(Running)狀態(tài)岭辣。這也是線程進入運行(Running)狀態(tài)的唯一方式吱晒。 - 阻塞(BLOCKED):線程在運行過程中,會由于各種原因進入阻塞狀態(tài):
- 線程通過調(diào)用sleep方法進入睡眠狀態(tài)沦童;
- 線程調(diào)用一個在I/O上被阻塞的操作仑濒,即該操作在輸入輸出操作完成之前不會返回到它的調(diào)用者;
- 線程試圖得到一個鎖(synchronized等)偷遗,而該鎖正被其他線程持有墩瞳;
- 線程在等待某個觸發(fā)條件;
......
阻塞狀態(tài)指正在運行的線程沒有運行結(jié)束氏豌,暫時讓出了CPU時間片喉酌,此時其處于就緒(Ready)狀態(tài)的線程就可以獲取CPU時間片,進入運行狀態(tài)泵喘。
- 等待(Waiting):表示線程等待(或者說掛起)瞭吃,讓出CPU資源給其他線程使用
Waiting的線程一般在等待一些特殊的事件,比如通過wait()方法等待的線程在等待notify()方法涣旨,而通過join()方法等待的線程則會等待目標(biāo)線程的終止歪架。一旦等到了期望事件,線程就會再次執(zhí)行霹陡。 - 超時等待(Timed_Wating):處于這種狀態(tài)的線程不會被分配CPU執(zhí)行時間和蚪,不過無須無限期等待被其他線程顯示地喚醒,在達到一定時間后它們會自動喚醒烹棉。
- 終止(TERMINATED):表示線程已執(zhí)行完畢攒霹。當(dāng)線程的run()方法執(zhí)行完畢,或者主程序的main()函數(shù)完成時浆洗,我們就認為它終止了催束。這個線程對象也許是活的,但是伏社,它已經(jīng)不是一個單獨執(zhí)行的線程抠刺。線程一旦終止了塔淤,就不能復(fù)生也就是無法再次回到Runnable狀態(tài)。舉個例子速妖,你在淘寶下了一個訂單高蜂,訂單號相當(dāng)于線程編號,假如你把這個訂單取消了罕容,則這個訂單無法恢復(fù)备恤,就算重新下單同樣的商品訂單號也會不一樣(不是同一個線程)。在一個終止的線程上調(diào)用start()方法锦秒,會拋出java.lang.IllegalThreadStateException異常露泊。