【併發編程】線程狀態解析

1. 線程的幾種狀態

在Java中,一個線程從建立到消亡會經歷新建狀態(New)、就緒狀態(Runnable)、運行狀態(Running)、阻塞狀態(Blocked)和死亡狀態。在運行過程當中,線程會在這幾個狀態之間流轉。線程

線程狀態流轉圖

下面對這幾種狀態作下簡單解釋:對象

  • 新建狀態(New) 新建立了一個線程對象。blog

  • 就緒狀態(Runnable) 線程對象建立後,其餘線程調用了該對象的start()方法。該狀態的線程位於可運行線程池中,變得可運行,等待獲取CPU的使用權。生命週期

  • 運行狀態(Running) 就緒狀態的線程獲取了CPU,執行程序代碼。文檔

  • 阻塞狀態(Blocked) 阻塞狀態是線程由於某種緣由放棄CPU使用權,暫時中止運行。直到線程進入就緒狀態,纔有機會轉到運行狀態。阻塞的狀況分三種同步

    等待阻塞(WAITING):運行的線程執行wait()方法,JVM會把該線程放入等待池中。
    同步阻塞(BLOCKED):運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則JVM會把該線程放入鎖池中。
    其餘阻塞(TIMED_WAITING):運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置爲阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程從新轉入就緒狀態。it

  • 死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命週期。線程池

2. 三種阻塞狀態的對比。

對於線程的新建、就緒、運行和死亡狀態,咱們都比較好理解。線程的三種阻塞狀態的含義可能會讓人比較困惑。下面就來解釋下這三種狀態的區別:請求

1. 等待阻塞狀態(TIMED_WAITING)
Java文檔官方定義TIMED_WAITING狀態爲:「一個線程在一個特定的等待時間內等待另外一個線程完成一個動做會在這個狀態」。調用下面的這些方法會讓線程進入TIMED_WAITING狀態。程序

  • Thread#sleep();
  • Object#wait() 並加了超時參數;
  • Thread#join() 並加了超時參數;
  • LockSupport#parkNanos();
  • LockSupport#parkUntil()。

2. WAITING狀態
Java文檔官方定義WAITING狀態是:「一個線程在等待另外一個線程執行一個動做時在這個狀態。」

當線程調用如下方法時會進入WAITING狀態:

  • Object#wait() 並且不加超時參數
  • Thread#join() 並且不加超時參數
  • LockSupport#park()。

在對象上的線程調用了Object.wait()會進入WAITING狀態,直到另外一個線程在這個對象上調用了Object.notify()或Object.notifyAll()方法才能恢復。一個調用了Thread.join()的線程會進入WAITING狀態直到一個特定的線程來結束。

2. BLOCKED狀態 Java文檔官方定義BLOCKED狀態是:「這種狀態是指一個阻塞線程在等待monitor鎖。」

相關文章
相關標籤/搜索