Java線程狀態介紹與示例——線程的生命週期

已發表: 2019-01-11
Java 線程狀態介紹與示例

線程狀態

下圖說明了 Java 線程在其生命週期中的任何時候可能處於的各種狀態,以及哪些方法調用會導致轉換到另一個狀態。 該圖不是一個完整的有限狀態圖,而是一個線程生命中更有趣和更常見的方面的概述。

如果您有以下任何問題,那麼您來對地方了:

  • Java中線程的生命週期
  • Java中線程的生命週期和狀態
  • 了解 Java 線程狀態

本頁的其餘部分根據其狀態討論Thread's life cycle

Java 線程狀態與示例

新線程

下面的語句創建了一個新線程,但沒有啟動它,從而使線程處於圖中標記為 New Thread 的狀態。

當一個線程處於New Thread狀態時,它只是一個空的 Thread 對象。 尚未為其分配系統資源。 因此當線程處於這種狀態時,只能啟動或停止線程; 當線程處於此狀態時調用除start()stop()之外的任何其他方法都沒有意義,並導致 IllegalThreadStateException。

可運行

現在考慮這兩行代碼:

start()方法創建運行線程所需的系統資源,調度線程運行,並調用線程的run()方法。 此時線程處於“可運行”狀態。 這種狀態稱為“Runnable”而不是“Running”,因為線程在這種狀態下可能實際上並未運行。 許多計算機只有一個處理器,因此不可能同時運行所有“可運行”線程。

因此,Java 運行時系統必須實現一個調度方案,在所有“可運行”線程之間共享處理器。 但是,對於大多數目的,您可以將“可運行”狀態簡單地視為“正在運行”。 當一個線程正在運行時——它是“可運行的”並且是當前線程——它的run()中的指令是按順序執行的。

不可運行

當以下四個事件之一發生時,線程進入Not Runnable狀態:

  • 有人調用它的suspend()方法
  • 有人調用它的sleep()方法
  • 線程使用它的wait()方法等待條件變量
  • 線程在 I/O 上阻塞。

例如,此代碼段中的粗體行

使myThread休眠 10 秒(10,000 毫秒)。 在這 10 秒內,即使處理器可用, myThread也不會運行。 10 秒後, myThread再次變為“可運行”,現在如果處理器可用, myThread將運行。

對於上面列出的進入“不可運行”狀態的每個“入口”,都有一個特定且不同的逃生路線將線程返回到“可運行”狀態。 逃生路線僅適用於其相應的“入口”。 例如,如果一個線程已經進入睡眠狀態,那麼在線程再次變為“可運行”之前必須經過指定的毫秒數。 在休眠線程上調用resume()無效。

以下指示了進入“不可運行”狀態的每個入口的逃生路線。

  • 如果線程已進入睡眠狀態,則必須經過指定的毫秒數。
  • 如果一個線程被掛起,那麼必須有人調用它的resume()方法。
  • 如果線程正在等待條件變量,則擁有該變量的任何對像都必須通過調用notify()notifyAll()放棄它。
  • 如果線程在 I/O 上被阻塞,則指定的 I/O 命令必須完成。
java線程教程

死的

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

在循環和run()方法完成後,具有此run()方法的線程將自然死亡。

你也可以隨時通過調用它的stop()方法來終止一個線程。 此代碼片段。

創建並啟動myThread然後讓當前線程休眠 10 秒。 噹噹前線程喚醒時,代碼段中的粗線將殺死myThread

stop()方法在線程上拋出一個 ThreadDeath 對象來殺死它。 因此,當一個線程以這種方式被殺死時,它會異步死亡。 線程在實際接收到 ThreadDeath 異常時將死亡。

非法線程狀態異常

當您調用線程上的方法並且該線程的狀態不允許該方法調用時,運行時系統會引發 IllegalThreadStateException。 例如,當您在不是“可運行”的線程上調用suspend()時,會引發 IllegalThreadStateException。

如本課到目前為止的各種線程示例所示,當您調用一個可以拋出異常的線程方法時,您必須要么捕獲並處理異常,要么聲明調用方法拋出未捕獲的異常。

isAlive() 方法

關於線程狀態的最後一句話:Thread 類的編程接口包括一個名為isAlive()的方法。 如果線程已啟動且未停止,則isAlive()返回 true。 因此,如果isAlive()方法返回false ,您就知道該線程是“新線程”或“死線程”。

如果isAlive()方法返回true ,你就知道線程要么是“Runnable”,要么是“Not Runnable”。 您無法區分“新線程”和“死線程”; 您也無法區分“可運行”線程和“不可運行”線程。

在查看複雜的線程示例時,在網上發現了這個非常棒的教程。 每個人都應該仔細閱讀這篇文章。