Java 多線程狀態轉換


線程基本狀態圖

    圖中是線程運行的基本狀態:線程調用start()方法開始後,就進入到可運行狀態,隨着CPU的資源調度在運行和可運行之間切換;遇到阻塞則進入阻塞狀態。二三的狀態圖中只不過線程被阻塞的情況分爲很多種,後面的圖是細化說明。  

New --> Runnable

    當一個線程執行了start方法後,不代表這個線程就會立即被執行,只代表這個線程處於可運行的狀態,最終由OS的線程調度來決定哪個可運行狀態下的線程被執行。 

Running --> Runnable

  • Thread.yield()
  • 一個線程一次被選中執行是有時間限制的,這個時間段叫做CPU的時間片,當時間片用完但線程還沒有結束時,這個線程又會變爲可運行狀態,等待OS的再次調度;

Running --> Blocked

  • 在一個運行中的線程等待用戶輸入
  • 調用Thread.sleep()
  • 調用了其他線程的join()方法

Blocked --> Runnable

  • 阻塞狀態的線程用戶輸入完畢
  • sleep時間到
  • join的線程結束


同步的線程狀態圖

Lock pool --> Runnable

當資源被一個線程訪問時,上鎖,其他線程就進入了一個鎖池(Lock pool)當鎖被釋放,其他線程獲得了鎖,就變爲可運行狀態。


加入線程間的相互作用  

               
  線程調用了wait()方法之後,釋放掉鎖,進入等待池(Wait pool) ;收到通知之後等待獲取鎖,獲取鎖之後纔可以運行。

 

線程被阻塞可能是由於下面五方面的原因:(《Thinking in Java》)

1.調用sleep(毫秒數),使線程進入睡眠狀態。在規定時間內,這個線程是不會運行的。

2.用suspend()暫停了線程的執行。除非收到resume()消息,否則不會返回“可運行”狀態。

3.用wait()暫停了線程的執行。除非線程收到notify()或notifyAll()消息,否則不會變成“可運行”狀態。

4.線程正在等候一些IO操作完成。

5.線程試圖調用另一個對象的“同步”方法,但那個對象處於鎖定狀態,暫時無法使用。


線程同步各個方法的區別

  • Thread.yield()當前運行的線程變成可運行狀態。
  • t2.join() 使得當前線程處於阻塞狀態直到t2線程執行完畢。
  • Thread.sleep()使得當前線程處於阻塞狀態直到sleep的時間結束。
  • wait、notify、notifyAll方法是Object類的方法,其調用環境必須有synchronized的同步塊中調用,否則會拋java.lang.IllegalMonitorStateException異常。

 

發佈了46 篇原創文章 · 獲贊 35 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章