Java線程狀態介紹與示例——線程的生命週期
已發表: 2019-01-11
線程狀態
下圖說明了 Java 線程在其生命週期中的任何時候可能處於的各種狀態,以及哪些方法調用會導致轉換到另一個狀態。 該圖不是一個完整的有限狀態圖,而是一個線程生命中更有趣和更常見的方面的概述。
如果您有以下任何問題,那麼您來對地方了:
- Java中線程的生命週期
- Java中線程的生命週期和狀態
- 了解 Java 線程狀態
本頁的其餘部分根據其狀態討論Thread's life cycle
。

新線程
下面的語句創建了一個新線程,但沒有啟動它,從而使線程處於圖中標記為 New Thread 的狀態。
1 |
Thread myThread = new MyThreadClass ( ) ; |
當一個線程處於New Thread
狀態時,它只是一個空的 Thread 對象。 尚未為其分配系統資源。 因此當線程處於這種狀態時,只能啟動或停止線程; 當線程處於此狀態時調用除start()
或stop()
之外的任何其他方法都沒有意義,並導致 IllegalThreadStateException。
可運行
現在考慮這兩行代碼:
1 2 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; |
start()
方法創建運行線程所需的系統資源,調度線程運行,並調用線程的run()
方法。 此時線程處於“可運行”狀態。 這種狀態稱為“Runnable”而不是“Running”,因為線程在這種狀態下可能實際上並未運行。 許多計算機只有一個處理器,因此不可能同時運行所有“可運行”線程。
因此,Java 運行時系統必須實現一個調度方案,在所有“可運行”線程之間共享處理器。 但是,對於大多數目的,您可以將“可運行”狀態簡單地視為“正在運行”。 當一個線程正在運行時——它是“可運行的”並且是當前線程——它的run()
中的指令是按順序執行的。
不可運行
當以下四個事件之一發生時,線程進入Not Runnable
狀態:
- 有人調用它的
suspend()
方法 - 有人調用它的
sleep()
方法 - 線程使用它的
wait()
方法等待條件變量 - 線程在 I/O 上阻塞。
例如,此代碼段中的粗體行
1 2 3 4 5 6 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { myThread . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } |
使myThread
休眠 10 秒(10,000 毫秒)。 在這 10 秒內,即使處理器可用, myThread
也不會運行。 10 秒後, myThread
再次變為“可運行”,現在如果處理器可用, myThread
將運行。
對於上面列出的進入“不可運行”狀態的每個“入口”,都有一個特定且不同的逃生路線將線程返回到“可運行”狀態。 逃生路線僅適用於其相應的“入口”。 例如,如果一個線程已經進入睡眠狀態,那麼在線程再次變為“可運行”之前必須經過指定的毫秒數。 在休眠線程上調用resume()
無效。
以下指示了進入“不可運行”狀態的每個入口的逃生路線。
- 如果線程已進入睡眠狀態,則必須經過指定的毫秒數。
- 如果一個線程被掛起,那麼必須有人調用它的
resume()
方法。 - 如果線程正在等待條件變量,則擁有該變量的任何對像都必須通過調用
notify()
或notifyAll()
放棄它。 - 如果線程在 I/O 上被阻塞,則指定的 I/O 命令必須完成。

死的
線程可能以兩種方式死亡:自然原因或被殺死(停止)。 當其run()
方法正常退出時,線程自然死亡。 例如,該方法中的while
循環是一個有限循環——它將迭代 100 次然後退出。

1 2 3 4 5 6 7 |
public void run ( ) { int i = 0 ; while ( i < 100 ) { i ++ ; System . out . println ( "i = " + i ) ; } } |
在循環和run()
方法完成後,具有此run()
方法的線程將自然死亡。
你也可以隨時通過調用它的stop()
方法來終止一個線程。 此代碼片段。
1 2 3 4 5 6 7 |
Thread myThread = new MyThreadClass ( ) ; myThread . start ( ) ; try { Thread . currentThread ( ) . sleep ( 10000 ) ; } catch ( InterruptedException e ) { } myThread . stop ( ) ; |
創建並啟動myThread
然後讓當前線程休眠 10 秒。 噹噹前線程喚醒時,代碼段中的粗線將殺死myThread
。
stop()
方法在線程上拋出一個 ThreadDeath 對象來殺死它。 因此,當一個線程以這種方式被殺死時,它會異步死亡。 線程在實際接收到 ThreadDeath 異常時將死亡。
非法線程狀態異常
當您調用線程上的方法並且該線程的狀態不允許該方法調用時,運行時系統會引發 IllegalThreadStateException。 例如,當您在不是“可運行”的線程上調用suspend()
時,會引發 IllegalThreadStateException。
如本課到目前為止的各種線程示例所示,當您調用一個可以拋出異常的線程方法時,您必須要么捕獲並處理異常,要么聲明調用方法拋出未捕獲的異常。
isAlive() 方法
關於線程狀態的最後一句話:Thread 類的編程接口包括一個名為isAlive()
的方法。 如果線程已啟動且未停止,則isAlive()
返回 true。 因此,如果isAlive()
方法返回false ,您就知道該線程是“新線程”或“死線程”。
如果isAlive()
方法返回true ,你就知道線程要么是“Runnable”,要么是“Not Runnable”。 您無法區分“新線程”和“死線程”; 您也無法區分“可運行”線程和“不可運行”線程。
在查看複雜的線程示例時,在網上發現了這個非常棒的教程。 每個人都應該仔細閱讀這篇文章。