目次
1. スレッドの状態 (ライフサイクル)
2. 操作スレッドのステータス
2.1. 新規作成ステータス (NEW)
2.2. 実行可能状態 (RUNNABLE)
プロセス全体は次のようになります: スレッドは最初にオブジェクトの同期メソッドでオブジェクト ロックを取得し、wait メソッドが実行されると、スレッドはオブジェクト ロックを解放し、スレッドはこのオブジェクトの待機キューに入ります。別のスレッドが同じオブジェクトのロックを取得するのを待ち、その後、notify() または NoticeAll() メソッドを通じてオブジェクトの待機キュー内のスレッドをウェイクアップします。
2.5.计时等待状态(TIMED_WAITING)
2.6.终止(TERMINATED)
3.查看线程的6种状态
ホームページ Java &#&チュートリアル Java スレッドの 6 つの状態とライフサイクルとは何ですか?

Java スレッドの 6 つの状態とライフサイクルとは何ですか?

May 02, 2023 pm 12:07 PM
java

    1. スレッドの状態 (ライフサイクル)

    スレッドは、特定の時点で 1 つの状態にのみなりえます。

    スレッドには次の 6 つの状態があります:

    • New (新しく作成された): 未開始のスレッド;

    • Runnable (実行可能) ): オペレーティング システムのリソースを待機する必要がある実行可能なスレッド;

    • Blocked (ブロック済み): モニター ロックの待機中にブロックされたスレッド;

    • Waiting (待機中): ウェイクアップ状態を待機し、別のスレッドがウェイクアップするまで無期限に待機します;

    • 時間制限された待機 (時間制限された待機): 指定された時間内で待機します。待機時間 別のスレッドが操作を実行するスレッド;

    • 終了: 終了したスレッド。

    スレッドの現在の状態を確認するには、getState メソッドを呼び出すことができます。

    スレッド状態の関係図

    注: 点線のボックス (すべて大文字の英語) ステータスは Java スレッドのステータスです。

    Java スレッドの 6 つの状態とライフサイクルとは何ですか?

    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 つの状態とライフサイクルとは何ですか?

    最终的执行结果如图。

    注意:因为案例中使用了独立线程来打印不同线程的状态,会出现状态打印稍微延迟的情况。

    以上がJava スレッドの 6 つの状態とライフサイクルとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

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

    AI Clothes Remover

    AI Clothes Remover

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

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    AI Hentai Generator

    AI Hentai Generator

    AIヘンタイを無料で生成します。

    ホットツール

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

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

    ゼンドスタジオ 13.0.1

    ゼンドスタジオ 13.0.1

    強力な PHP 統合開発環境

    ドリームウィーバー CS6

    ドリームウィーバー CS6

    ビジュアル Web 開発ツール

    SublimeText3 Mac版

    SublimeText3 Mac版

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

    Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

    Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

    Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

    Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

    Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

    Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

    ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

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

    Javaのアームストロング数 Javaのアームストロング数 Aug 30, 2024 pm 04:26 PM

    Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

    Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

    Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

    Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

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

    Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

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

    See all articles