Java スレッドの 6 つの状態とライフサイクルとは何ですか?
1. スレッドの状態 (ライフサイクル)
スレッドは、特定の時点で 1 つの状態にのみなりえます。
スレッドには次の 6 つの状態があります:
New (新しく作成された): 未開始のスレッド;
Runnable (実行可能) ): オペレーティング システムのリソースを待機する必要がある実行可能なスレッド;
Blocked (ブロック済み): モニター ロックの待機中にブロックされたスレッド;
Waiting (待機中): ウェイクアップ状態を待機し、別のスレッドがウェイクアップするまで無期限に待機します;
時間制限された待機 (時間制限された待機): 指定された時間内で待機します。待機時間 別のスレッドが操作を実行するスレッド;
終了: 終了したスレッド。
スレッドの現在の状態を確認するには、getState メソッドを呼び出すことができます。
スレッド状態の関係図
注: 点線のボックス (すべて大文字の英語) ステータスは Java スレッドのステータスです。
2. 操作スレッドのステータス
2.1. 新規作成ステータス (NEW)
は、スレッドのインスタンス化が完了した後のことを意味します、スレッドは開始されていないステータスです。
スレッドは 3 つの方法で作成できます
Thread クラスの run() メソッドをオーバーライドします
Runnable インターフェイスを実装します
Callable インターフェイスの実装
3 つのメソッドをまとめた簡単な例です
public class Demo { public static void main(String[] args) throws ExecutionException, InterruptedException { /** * 1.直接重写run() 或继承Thread类再重写run() */ Thread thread = new Thread() { @Override public void run() { System.out.println("Thread"); } }; // 开启线程 thread.start(); /** * 2.lambda、内部类或线程类方式实现Runnable接口,实现run()方法 * 再交给Thread 类 */ Thread runThread = new Thread(() -> { System.out.println("Runnable"); }); // 开启线程 runThread.start(); /** * 3.lambda、内部类或线程类方式实现Callable接口,实现call()方法 * 再交给Thread 类:FutureTask本质也是Runnable实现类 */ FutureTask<String> futureTask = new FutureTask<String>(() -> { System.out.println("Callable"); return "CallableThread"; }); Thread callThread = new Thread(futureTask); // 开启线程 callThread.start(); // 获取call()方法的返回值 String s = futureTask.get(); System.out.println("call()方法的返回值:"+s); } }
run() または call() を書き換えないでくださいこのメソッドは、Thread クラスによって作成されたスレッドを直接インスタンス化しますが、実際的な意味はありません。
Callable メソッドで作成されたスレッドのみが、スレッドの戻り値を取得できます。
2.2. 実行可能状態 (RUNNABLE)
この状態は、スレッドがオブジェクトをインスタンス化し、start() メソッドを呼び出した後に入る状態を指します。スレッドは実行可能な状態であり、プロセッサなどのリソースがあればプログラムを実行することができます。
この状態には、オペレーティング システム レベルで 2 つのステップ (スレッド準備完了とスレッド実行中) が含まれていますが、Java スレッド状態では、これら 2 つのステップをまとめて Runnable (実行可能) 状態と呼びます。
スレッドは準備完了状態から実行状態に変わります。重要な点は、スレッドが CPU リソース (CPU タイム スライス) を取得したかどうかを確認することです。取得した人がそれを実行します。取得しなかった場合は実行されます。つかまないで、待ってください。 CPU タイムスライス (実行時間) は約 10 ミリ秒と非常に短いため、スレッドの切り替え時間は非常に短く、準備完了状態から実行状態に移行する時間も非常に短く、この状態は実行中にほとんど見えません。そのため、Java では、スレッドが実行できるかどうかに焦点を当て、スレッドを他の状態と区別して、この 2 つを全体としてみなし、スレッドの開発をさらに簡素化します。プログラムを長時間実行する必要があり (無限ループの作成など)、その実行が CPU タイム スライス内に完了しない場合、スレッドは次の CPU タイム スライスを取得する必要があります。プログラムの実行を継続します。取得していない場合は、プログラムの実行を継続できます。その後、スレッド内のプログラムの実行が完了するまで取得を続ける必要があります。
実際、このシナリオは以前にも見たことがあると思います。たとえば、複数のスレッドが同じプログラムを実行し、ログを同じファイルに出力する場合、異なるスレッドのログが混在するため、トラブルシューティングの質問です。この問題を解決する一般的な方法は、まずログを異なるスレッドの異なるファイルに出力すること、次にログ情報を文字列オブジェクトに保存し、プログラムの終了時に一度にログ情報をファイルに出力することです。 2 番目の方法は、CPU のタイム スライスを使用してログ情報の出力を完了する方法です。
注: プログラムは、新しく作成された状態のスレッドでのみ start() メソッドを呼び出すことができます。新しく作成されていない状態のスレッドでは start() メソッドを呼び出さないでください。これにより、IllegalThreadStateException 例外が発生します。
2.3. ブロック状態 (BLOCKED) スレッドはmonitor ロック を待機しており、ブロックされています。 1 つのスレッドがロックを取得したが解放せず、他のスレッドもロックを取得しに来ましたが、ロックを取得できずにブロック状態になりました。 ブロックされた状態は、複数のスレッドによる同時アクセス下でのみ存在します。これは、スレッド自体が「待機」状態になることによって引き起こされる後者の 2 つのタイプのブロックとは異なります。
状態を入力してください- 同期されたコード ブロック/メソッドを入力してください
- ロックが取得されていません
- モニターロックを取得しました
- 2.4. ウェイクアップを待ちますstate (WAITING)
プロセス全体は次のようになります: スレッドは最初にオブジェクトの同期メソッドでオブジェクト ロックを取得し、wait メソッドが実行されると、スレッドはオブジェクト ロックを解放し、スレッドはこのオブジェクトの待機キューに入ります。別のスレッドが同じオブジェクトのロックを取得するのを待ち、その後、notify() または NoticeAll() メソッドを通じてオブジェクトの待機キュー内のスレッドをウェイクアップします。
プロセス全体からわかるように、
wait ()、notify ()、notifyAll () メソッドは、スレッドが実行を続行する前にロックを取得する必要があるため、これら 3 つのメソッドは次のようになります。必須 実行のために同期されたコード ブロック/メソッドに配置します。そうでない場合は、例外 java.lang.IllegalMonitorStateException が報告されます。
在同步代码块中,线程进入WAITING 状态时,锁会被释放,不会导致该线程阻塞。反过来想下,如果锁没释放,那其他线程就没办法获取锁,也就没办法唤醒它。
进入状态
object.wait()
thread.join()
LockSupport.park()
退出状态
object.notify()
object.notifyall()
LockSupport.unpark()
2.5.计时等待状态(TIMED_WAITING)
一般是计时结束就会自动唤醒线程继续执行后面的程序,对于Object.wait(long) 方法还可以主动通知唤醒。
注意:Thread类下的sleep() 方法可以放在任意地方执行;而wait(long) 方法和wait() 方法一样,需要放在同步代码块/方法中执行,否则报异常:java.lang.IllegalMonitorStateException。
进入状态
Thread.sleep(long)
Object.wait(long)
Thread.join(long)
LockSupport.parkNanos(long)
LockSupport.parkNanos(Object blocker, long nanos)
LockSupport.parkUntil(long)
LockSupport.parkUntil(Object blocker, long deadline)
注:blocker 参数为负责此线程驻留的同步对象。
退出状态
计时结束
LockSupport.unpark(Thread)
object.notify()
object.notifyall()
2.6.终止(TERMINATED)
线程执行结束
run()/call() 执行完成
stop()线程
错误或异常>>意外死亡
stop() 方法已弃用。
3.查看线程的6种状态
通过一个简单的例子来查看线程出现的6种状态。
案例
public class Demo3 { private static Object object ="obj"; public static void main(String[] args) throws InterruptedException { Thread thread0 = new Thread(() -> { try { // 被阻塞状态(BLOCKED) synchronized (object){ System.out.println("thread0 进入:等待唤醒状态(WAITING)"); object.wait(); System.out.println("thread0 被解除完成:等待唤醒状态(WAITING)"); } System.out.println("thread0 "+Thread.currentThread().getState()); } catch (InterruptedException e) { e.printStackTrace(); } }); // 新创建状态(NEW) System.out.println(thread0.getName()+":"+thread0.getState()); Thread thread1 = new Thread(() -> { try { System.out.println("thread1 进入:计时等待状态(TIMED_WAITING)"); Thread.sleep(2); System.out.println("thread1 出来:计时等待状态(TIMED_WAITING)"); } catch (InterruptedException e) { e.printStackTrace(); } // 被阻塞状态(BLOCKED) synchronized (object){ System.out.println("thread1 解除:等待唤醒状态(WAITING)"); object.notify(); System.out.println("thread1 解除完成:等待唤醒状态(WAITING)"); } System.out.println("thread1 "+Thread.currentThread().getState()); }); // 新创建状态(NEW) System.out.println(thread1.getName()+":"+thread1.getState()); printState(thread0); printState(thread1); // 可运行状态(RUNNABLE) thread0.start(); // 可运行状态(RUNNABLE) thread1.start(); } // 使用独立线程来打印线程状态 private static void printState(Thread thread) { new Thread(()->{ while (true){ System.out.println(thread.getName()+":"+thread.getState()); if (thread.getState().equals(Thread.State.TERMINATED)){ System.out.println(thread.getName()+":"+thread.getState()); break; } } }).start(); } }
执行结果:简化后的输出结果
Thread-0:NEW
Thread-1:NEW
Thread-0:RUNNABLE
Thread-1:RUNNABLE
thread0 进入:等待唤醒状态(WAITING)
Thread-1:BLOCKED
thread1 进入:计时等待状态(TIMED_WAITING)
Thread-0:BLOCKED
Thread-0:WAITING
……
Thread-0:WAITING
Thread-1:BLOCKED
Thread-1:TIMED_WAITING
……
Thread-1:TIMED_WAITING
Thread-1:BLOCKED
……
Thread-1:BLOCKED
Thread-0:WAITING
……
Thread-0:WAITING
thread1 出来:计时等待状态(TIMED_WAITING)
Thread-0:WAITING
Thread-1:BLOCKED
thread1 解除:等待唤醒状态(WAITING)
Thread-1:BLOCKED
Thread-0:WAITING
Thread-0:BLOCKED
thread1 解除完成:等待唤醒状态(WAITING)
Thread-1:BLOCKED
thread1 RUNNABLE
Thread-0:BLOCKED
Thread-1:TERMINATED
thread0 被解除完成:等待唤醒状态(WAITING)
Thread-0:BLOCKED
thread0 RUNNABLE
Thread-0:TERMINATED
最终的执行结果如图。
注意:因为案例中使用了独立线程来打印不同线程的状态,会出现状态打印稍微延迟的情况。
以上がJava スレッドの 6 つの状態とライフサイクルとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。
