首頁 >Java >Java基礎 >java線程的幾種狀態是什麼?

java線程的幾種狀態是什麼?

青灯夜游
青灯夜游原創
2020-07-24 11:37:266919瀏覽

java執行緒的5種狀態:1、初始狀態。 2.可運行狀態,位於可運行執行緒池中,等待被執行緒調度選中,取得cpu的使用權。 3、運行狀態。 4.阻塞狀態,指線程因為某些原因放棄了cpu使用權。 5.死亡狀態,死亡的線程不可再復生。

java線程的幾種狀態是什麼?

Java中的執行緒的生命週期大致可分為5種狀態。

1、初始狀態(NEW):新建立了一個執行緒物件。

2、可運行(RUNNABLE):執行緒物件建立後,其他執行緒(如main執行緒)呼叫了該物件的start()方法。此狀態的執行緒位於可運行執行緒池中,等待被執行緒調度選中,取得cpu的使用權 。

3、運行(RUNNING):可運行狀態(runnable)的執行緒獲得了cpu 時間片(timeslice) ,執行程式碼。

4. 阻塞(BLOCKED):阻塞狀態是指執行緒因為某些原因放棄了cpu 使用權,也即讓出了cpu timeslice,暫時停止運作。直到執行緒進入可運行(runnable)狀態,才有機會再次獲得cpu timeslice 轉到運行(running)狀態。阻塞的情況分為三種: 

(1)、等待阻塞:執行(running)的執行緒執行o.wait()方法,JVM會把該執行緒放入等待佇列(waitting queue)中。

(2)、同步阻塞:執行(running)的執行緒在取得物件的同步鎖定時,若該同步鎖定被別的執行緒佔用,則JVM會把該執行緒放入鎖定池(lock pool )中。

(3)、其他阻塞:當執行(running)的執行緒執行Thread.sleep(long ms)或t.join()方法,或發出了I/O請求時,JVM會把該執行緒置為阻塞狀態。當sleep()狀態逾時、join()等待執行緒終止或逾時、或I/O處理完畢時,執行緒重新轉入可運行(runnable)狀態。

5、死亡(DEAD):執行緒run()、main() 方法執行結束,或因異常退出了run()方法,則該執行緒結束生命週期。死亡的線不可再復生。

一、執行緒的狀態圖

java線程的幾種狀態是什麼?

#二、初始狀態

實現Runnable介面與繼承Thread可以得到一個執行緒類,new一個實例出來,執行緒就進入了初始狀態

#三、可運行狀態

##1、可運行狀態只是說你資格運行,調度程式沒有挑選到你,你就永遠是可運行狀態。

2、呼叫執行緒的start()方法,此執行緒進入可運行狀態。

3、目前執行緒sleep()方法結束,其他執行緒join()結束,等待使用者輸入完畢,某個執行緒拿到物件鎖定,這些執行緒也會進入可運作狀態。

4、目前執行緒時間片用完了,呼叫目前執行緒的yield()方法,目前執行緒進入可運行狀態。

5、鎖定池裡的執行緒拿到物件鎖定後,進入可運行狀態。

四、運行狀態

執行緒調度程序從可運行池中選擇一個執行緒作為目前執行緒時執行緒所處的狀態。這也是執行緒進入運行狀態的唯一一種方式。

五、死亡狀態

1、當執行緒的run()方法完成時,或是主執行緒的main()方法完成時,我們就認為它死去。這個線程物件也許是活的,但是,它已經不是一個單獨執行的線程。線一旦死亡,就不能復生。

2、在一個死去的執行緒上呼叫start()方法,會拋出java.lang.IllegalThreadStateException例外。

六、阻塞狀態

1、目前執行緒T呼叫Thread.sleep()方法,目前執行緒進入阻塞狀態。

2、運行在目前執行緒裡的其它執行緒t2呼叫join()方法,目前執行緒進入阻塞狀態。

3、等待使用者輸入的時候,目前執行緒進入阻塞狀態。

七、等待佇列(本來是Object裡的方法,但影響了執行緒)

1、呼叫obj的wait(), notify()方法前,必須取得obj鎖,也就是必須寫在synchronized(obj) 程式碼段內。

2、與等待佇列相關的步驟和圖

  • 線程1取得物件A的鎖,正在使用物件A。

  • 執行緒1呼叫物件A的wait()方法。

  • 線程1釋放物件A的鎖,並馬上進入等待佇列。

  • 鎖定池裡面的物件爭搶物件A的鎖定。

  • 線程5取得物件A的鎖,進入synchronized區塊,使用物件A。

  • 線程5呼叫物件A的notifyAll()方法,喚醒所有線程,所有執行緒進入鎖定池。 ||||| 執行緒5呼叫物件A的notify()方法,喚醒一個線程,不知道會喚醒誰,被喚醒的那個執行緒進入鎖定池。

  • notifyAll()方法所在synchronized結束,執行緒5釋放物件A的鎖定。

  • 鎖定池裡面的執行緒爭搶物件鎖,但線程1什麼時候能搶到就不知道了。 ||||| 原本鎖定池 第6步被喚醒的執行緒一起爭搶物件鎖定。

    java線程的幾種狀態是什麼?

八、鎖定池狀態

目前執行緒想呼叫物件A的同步方法時,發現物件A的鎖被別的執行緒佔有,此時當前執行緒進入鎖池狀態。簡言之,鎖池裡面放的都是想爭奪物件鎖的執行緒。

當一個執行緒1被另外一個執行緒2喚醒時,1執行緒進入鎖定池狀態,去爭奪物件鎖定。

鎖定池是在同步的環境下才有的概念,一個物件對應一個鎖定池。

九、幾個方法的比較

Thread.sleep(long millis),一定是當前執行緒呼叫此方法,當前執行緒進入阻塞,但不釋放對象鎖,millis後執行緒自動甦醒進入可運作狀態。作用:給其它執行緒執行機會的最佳方式。

Thread.yield(),一定是當前執行緒呼叫此方法,當前執行緒放棄取得的cpu時間片,由運行狀態變會可運行狀態,讓OS再次選擇執行緒。作用:讓相同優先權的執行緒輪流執行,但不保證一定會輪流執行。實際上無法保證yield()達到讓步目的,因為讓步的執行緒還有可能被執行緒調度程序再次選取。 Thread.yield()不會導致阻塞。

t.join()/t.join(long millis),當前執行緒裡呼叫其它執行緒1的join方法,目前執行緒阻塞,但不釋放物件鎖,直到執行緒1執行完畢或millis時間到,當前執行緒進入可運行狀態。

obj.wait(),目前執行緒呼叫物件的wait()方法,目前執行緒釋放物件鎖,進入等待佇列。依靠notify()/notifyAll()喚醒或wait(long timeout)timeout時間到自動喚醒。

obj.notify()喚醒在此物件監視器上等待的單一線程,選擇是任意性的。 notifyAll()喚醒在此物件監視器上等待的所有執行緒。

推薦教學:《java教學

以上是java線程的幾種狀態是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn