您好,登錄后才能下訂單哦!
這篇文章主要介紹“java線程有多少種狀態”,在日常操作中,相信很多人在java線程有多少種狀態問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java線程有多少種狀態”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
人有生老病死。同樣的,線程有自己的生命周期。在 Java 中線程的生命周期中一共有 6 種狀態:
New(新創建)
Runnable(可運行)
Blocked(被阻塞)
Waiting(等待)
Timed Waiting(計時等待)
Terminated(被終止)
查看 Thread 類的源碼時,內部還定義了這樣一個枚舉類。這個枚舉類定義的就是線程的狀態,源碼如下:
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
PS:線程在任何時刻只可能處于以上 6 種的其中 1 種狀態,我們可以調用 getState () 查看線程的狀態。
我們知道線程有 6 種狀態。然而,它是如何切換的呢?狗哥根據自己的理解做了一張圖,接下來將根據這張圖詳細了解下線程狀態的切換。
線程的 6 種狀態
先注意 NEW 狀態:線程被 NEW 出來,但還沒調用 start 方法時,就處于這種狀態。一旦調用了 start 方法也就進入了 RUNNABLE 狀態。
處于 RUNNABLE 的線程,比較特殊。它還分兩種狀態:Running 和 Ready。也就是說,Java 中處于 Runnable 狀態的線程有可能正在執行,也有可能沒有正在執行,正在等待被分配 CPU 資源。
因此,我們可以推斷出,一個處于 Runnable 狀態的線程,當它運行到任務的一半時,執行該線程的 CPU 被調度去做其他事情,則該線程暫時不運行。但是,它的狀態依然不變,還是 Runnable,因為它有可能隨時被調度回來繼續執行任務。
也就是說:處于 Runnable 狀態的線程并不一定在運行。這點在面試中常問,小伙伴們要注意了。
再來看看最簡單的 Blocked 狀態,從 Runnable 進入 Blocked 只有一種可能:就是進入 synchronized 關鍵字保護的代碼,但是沒有獲取到 monitor 鎖。
線程的 6 種狀態
再來,看圖的右側,Blocked ----> Runnable 狀態:當處于 Blocked 狀態的線程獲取到鎖。
線程從 Runnable 進入 Waiting 狀態,有三種可能性:
沒有設置 Timeout 參數的 Object.wait () 方法。
沒有設置 Timeout 參數的 Thread.join () 方法。
LockSupport.park () 方法。
上面我們知道,線程進入 Blocked 狀態只可能是:進入 synchronized 保護的代碼,但是沒獲取到 monitor 鎖。然而,Java 中還有很多鎖,比如:ReentrantLock。線程在獲取這種鎖時,沒有搶到就會進入 Waiting 狀態,因為它本質上是調用了 LockSupport.park () 方法。
同樣的,調用 Object.wait () 和 Thread.join () 也會讓線程進入等待狀態。
Blocked 與 Waiting 的區別是:Blocked 在等待其他線程釋放 monitor 鎖,而 Waiting 則是在等待某個條件,比如 join 的線程執行完畢,或者是 notify ()/notifyAll ()。
線程的 6 種狀態
看 Waiting 右側,Waiting ----> Runnable:1、當執行了 LockSupport.unpark (),2、join 的線程運行結束,3、被中斷
看 Waiting 右側,Waiting ----> Blocked:我們看圖可以知道其他線程調用 notify () 或 notifyAll () 來喚醒處于 Waiting 的線程,它會直接進入 Blocked 狀態。這是為什么?
其他線程能調用 notify () 或 notifyAll () 試圖喚醒 Waiting 狀態線程,說明必須持有同一個 monitor 鎖,也就是說處于 Waiting 的線程被喚醒后并不能馬上搶到 monitor 鎖,所以它必須先進入 Blocked 狀態。而喚醒它的線程執行完畢釋放鎖后,它能搶到鎖就從 Blocked 進入 Runnable 狀態。
這種狀態與 Waiting 狀態的區別在于:有沒有時間限制,Timed Waiting 會等待超時,由系統自動喚醒,或者在超時前被喚醒信號喚醒。
有以下 5 種情況會讓線程進入 Timed Waiting 狀態:
設置 Timeout 參數的 Thread.sleep (time) 方法。
設置 Timeout 參數的 Object.wait (time) 方法。
設置 Timeout 參數的 Thread.join (time) 方法。
設置 Timeout 參數的 LockSupport.parkNanos (long nanos) 方法。
設置 Timeout 參數的 LockSupport.parkUntil (long deadline) 方法。
線程的 6 種狀態
看 Timed Waiting 右側,Timed Waiting ----> Blocked:跟 Waiting 一樣,其他線程執行 notify () 和 notifyAll (),當前線程也是先進入 Blocked 狀態,而后視鎖的獲取情況再決定是否進入 Runnable 狀態。
另外,Timed Waiting ----> Runnable :1、當前線程的超時時間到了且能直接獲取到鎖,2、join 的線程運行結束,3、被中斷,4、調用了 LockSupport.unpark (),這幾種情況會直接恢復到 Runnable,而無需經歷 Blocked 狀態。
最后一種,想要進入終止狀態就比較簡單了,有三種情況:
任務執行完畢,線程正常退出。
出現一個沒有捕獲的異常(比如直接調用 interrupt () 方法)。
到此,關于“java線程有多少種狀態”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。