線程包括哪些狀態?狀態之間是如何轉變的?


線程的生命周期

線程包括哪些狀態的問題說專業一點就是線程的生命周期。
不同的編程語言對線程的生命周期封裝是不同的。

 

Java 中線程的生命周期

Java 語言中線程共有六種狀態。

  1. NEW(初始化狀態)
  2. RUNNABLE(可運行 / 運行狀態)
  3. BLOCKED(阻塞狀態)
  4. WAITING(無限時等待)
  5. TIMED_WAITING(有限時等待)
  6. TERMINATED(終止狀態) 在操作系統層面,Java 線程中的 BLOCKED、WAITING、TIMED_WAITING 是一種狀態(休眠狀態)。即只要 Java 線程處於這三種狀態之一,就永遠沒有 CPU 的使用權。

如圖: 

 

Java 中線程的狀態的轉變

1. NEW 到 RUNNABLE 狀態

Java 剛創建出來的 Thread 對象就是 NEW 狀態,不會被操作系統調度執行。從 NEW 狀態轉變到 RUNNABLE 狀態調用線程對象的 start() 方法就可以了。

 

2. RUNNABLE 與 BLOCKED 的狀態轉變

  • synchronized 修飾的方法、代碼塊同一時刻只允許一個線程執行,其他線程只能等待,等待的線程會從 RUNNABLE 轉變到 BLOCKED 狀態。
  • 當等待的線程獲得 synchronized 隱式鎖時,就又會從 BLOCKED 轉變到 RUNNABLE 狀態。
    在操作系統層面,線程是會轉變到休眠狀態的,但是在 JVM 層面,Java 線程的狀態不會發生變化,即 Java 線程的狀態會保持 RUNNABLE 狀態。JVM 層面並不關心操作系統調度相關的狀態,因為在 JVM 看來,等待 CPU 使用權(操作系統層面處於可執行狀態)與等待 I/O(操作系統層面處於休眠狀態)沒有區別,都是在等待某個資源,都歸入了 RUNNABLE 狀態。
    Java 在調用阻塞式 API 時,線程會阻塞,指的是操作系統線程的狀態,並不是 Java 線程的狀態。

 

3. RUNNABLE 與 WAITING 的狀態轉變

  • 獲得 synchronized 隱式鎖的線程,調用無參數的 Object.wait() 方法,狀態會從 RUNNABLE 轉變到 WAITING;調用 Object.notify()、Object.notifyAll() 方法,線程可能從 WAITING 轉變到 RUNNABLE 狀態。
  • 調用無參數的 Thread.join() 方法。join() 是一種線程同步方法,如有一線程對象 Thread t,當調用 t.join() 的時候,執行代碼的線程的狀態會從 RUNNABLE 轉變到 WAITING,等待 thread t 執行完。當線程 t 執行完,等待它的線程會從 WAITING 狀態轉變到 RUNNABLE 狀態。
  • 調用 LockSupport.park() 方法,線程的狀態會從 RUNNABLE 轉變到 WAITING;調用 LockSupport.unpark(Thread thread) 可喚醒目標線程,目標線程的狀態又會從 WAITING 轉變為 RUNNABLE 狀態。

 

4. RUNNABLE 與 TIMED_WAITING 的狀態轉變

  • Thread.sleep(long millis)
  • Object.wait(long timeout)
  • Thread.join(long millis)
  • LockSupport.parkNanos(Object blocker, long deadline)
  • LockSupport.parkUntil(long deadline)
    TIMED_WAITING 和 WAITING 狀態的區別,僅僅是調用的是超時參數的方法。

 

5. RUNNABLE 到 TERMINATED 狀態

  • 線程執行完 run() 方法后,會自動轉變到 TERMINATED 狀態
  • 執行 run() 方法時異常拋出,也會導致線程終止
  • Thread類的 stop() 方法已經不建議使用

 

 來一道刷了進BAT的面試題?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM