線程的六種狀態(tài)
同一時間線程只能處于一種狀態(tài)
-
New
新創(chuàng)建 -
Runnable
可運行 -
Blocked
被阻塞 -
Waiting
等待 -
Timed Waiting
計時等待 -
Terminated
被終止
獲取當(dāng)前線程狀態(tài)
可以使用線程的getState()
獲取當(dāng)前線程的狀態(tài)
Thread thread = new Thread();
System.out.println(thread.getState());
新建狀態(tài)(New)
New
的意思是當(dāng)前線程新建出來但沒有啟動,比如新建一個線程時new Thread()
叉信,此時線程就處于New
狀態(tài)什乙,如果線程調(diào)用的了start()
方法液肌,此時線程開始執(zhí)行run()
下面的方法,這時候線程的狀態(tài)也就會從New
變成Runnable
狀態(tài)淑翼。
可運行狀態(tài)(Runnable)
在Java中萧吠,Runnable
狀態(tài)分為兩種糖声,一種是可能沒有運行豹悬,正在等待CPU調(diào)度資源分配給線程使用葵陵,另外一種是已經(jīng)正在運行。假設(shè)A線程正在執(zhí)行瞻佛,跑到一半分配的CPU資源被調(diào)度走做了別的事情脱篙,那么此時該線程會暫時不運行,等待重新分配CPU資源涤久,這個時候線程的狀態(tài)還是RUnnable
狀態(tài)不會做出改變涡尘。
阻塞狀態(tài)(Blocked)
線程從RUnnable
狀態(tài)變成Blocked
狀態(tài)只有一種途徑,就是當(dāng)線程進入到synchronized
沒有拿到當(dāng)前代碼塊對應(yīng)的monitor
鎖响迂,這個時候線程就會進入到Blocked
狀態(tài)。
等待狀態(tài)(Waiting)
線程從Runnable
進入Waiting
有以下三種情況:
- 線程調(diào)用了沒有設(shè)置
Timeout
參數(shù)的Object.wait()
方法细疚。 - 線程調(diào)用了沒有設(shè)置
Timeout
參數(shù)的Thread.join()
方法蔗彤。 - 線程調(diào)用了
LockSupport.park()
方法川梅。
Blocked
狀態(tài)是針對synchronized
的monitor
鎖的,但是java中有很多種鎖然遏,例如:ReentrantLock
贫途。在這些鎖中,如果線程沒有獲取到鎖待侵,就會直接進去Waiting
狀態(tài)丢早,其實本質(zhì)就是調(diào)用了LockSupport.park()
,進入到Waiting
狀態(tài)秧倾。
Blocked 和 Waiting 區(qū)別:
-
Blocked
等待其它線程釋放monitor
鎖怨酝。 -
Waiting
是等待其它條件,例如join()
執(zhí)行結(jié)束那先,或者是notify()
和notifyAll()
农猬。
計時等待(Timed Waiting)
與
Waiting
是一樣的。
線程進入到Timed Waiting
狀態(tài)有以下四種情況:
- 線程調(diào)用了設(shè)置時間參數(shù)的
Thread.sleep(long millis)
方法售淡。 - 線程調(diào)用了設(shè)置時間參數(shù)的
Object.wait(long timeout)
方法斤葱。 - 線程調(diào)用了設(shè)置時間參數(shù)的
Thread.join(long millis)
方法。 - 線程調(diào)用了設(shè)置時間參數(shù)的
LockSupport.parkNanos(long nanos)
和LockSupport.parkUntil(long deadline)
方法揖闸。
線程終止(Terminated)
線程進入到Terminated
有兩種情況:
-
run()
方法中代碼執(zhí)行完畢揍堕,正常退出。 - 出現(xiàn)沒有捕獲的異常汤纸,終止的
run()
方法鹤啡,意外退出。
流程圖
圖片原文:傳送門
原文發(fā)布在:傳送門