検索
ホームページJava&#&チュートリアルすべてのサブスレッドのタスクが完了した後にメインスレッドをシャットダウンする 4 つの方法

マルチスレッドは Java において非常に重要な知識です。ここでは Java スレッドのマルチスレッドについてまとめます。ぜひマスターしてください。

    • #メソッド 1 Thread.sleep

    • メソッド 2 ExecutorService

    • メソッド 3 スレッド.join

    • ##メソッド 4 Thread.yield および Thread.activeCount

##コードを書いているときにこのような状況に遭遇しました。各サブスレッドの実行状況を観察する必要があります。処理が実行されないと、

メイン#の後に他のサブスレッドが閉じられてしまいます。 ## メソッドが完了しても、すべてのサブスレッドの詳細な実行ステータスを観察することは不可能であるため、メインスレッドはシャットダウンする前にすべてのサブスレッドの実行が完了するまで待機する必要がありました。

main

関数に Thread を追加します。 sleep(time) ただし、この方法は待ち時間を人為的に設定する必要があるため、完璧ではありませんが、これはベストプラクティスではありません。いくつかの情報とブログを確認し、この目的を達成するための 4 つの方法を紹介します。方法 1 Thread.sleep これはベスト プラクティスではありませんが、最も一般的な方法です。

public static void main(String[] args) throws InterruptedException{        for(int i=0; i<10; i++){            new Thread("subthread" + i){
                @Override                public void run() {                    try {
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName() + "finished");
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }.start();
        }
        Thread.sleep(2000);
        System.out.println("main thread finished");
    }

実行結果:

subthread0finished
subthread1finished
subthread2finished
subthread6finished
subthread4finished
subthread5finished
subthread3finished
subthread9finished
subthread8finished
subthread7finished
main thread finished

メソッド 2 ExecutorService

は、スレッド プールを使用して実装できます。一般的に使用されるスレッド プール オブジェクトは # の実装です。 ##ExecutorService

インターフェイス。

shutdown

およびその他のメソッドを提供します。現在送信されているタスクが子スレッドで実行終了した後、Java プロセスが正常に終了することを確認します。結果は次のとおりです:

public static void main(String[] args) {        // 创建一个ExecutorService
        ExecutorService ex =  Executors.newCachedThreadPool();        for(int i=0; i<10; i++){            // 添加 task
            ex.submit(new Thread("subthread" + i){

                @Override                public void run() {                    try{
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName() + "finished");
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            });
        }        // 使用shutdown 会通知executorservice 停止添加其它task 它会等待所有子线程运行结束才退出Java进程
        ex.shutdown();
        System.out.println("main thread finished");

    }
このメソッドにはいくつかの小さな欠陥がありますが、出力情報から判断できます。メインスレッドが実際にはサブスレッドよりも前に実行を終了していることがわかります。そのため、このメソッドはサブスレッドの実行を保証することしかできません。 -thread はプログラムが終了する前に実行を終了できますが、サブスレッドの実行が終了した後にメインスレッドが実行されることは保証できません。したがって、コードを変更する必要があります。awaitTermination(time, timeunit)# を追加します。 ## より適切な待ち時間を設定し、サブスレッドの実行が完了するまで待ちます。<pre class='brush:php;toolbar:false;'>main thread finished pool-1-thread-3finished pool-1-thread-4finished pool-1-thread-2finished pool-1-thread-1finished pool-1-thread-5finished pool-1-thread-7finished pool-1-thread-8finished pool-1-thread-6finished pool-1-thread-9finished pool-1-thread-10finished</pre>実行結果:

public static void main(String[] args) {        // 创建一个ExecutorService
        ExecutorService ex =  Executors.newCachedThreadPool();        for(int i=0; i<10; i++){            // 添加 task
            ex.submit(new Thread("subthread" + i){

                @Override                public void run() {                    try{
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName() + "finished");
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            });
        }        // 使用shutdown 会通知executorservice 停止添加其它task 它会等待所有子线程运行结束才退出Java进程
        ex.shutdown();        try {            // 设置等待时间等待子线程运行完毕
            if(!ex.awaitTermination(2000, TimeUnit.MILLISECONDS)){                // 等待时间内子线程并未全部运行完毕就直接关闭
                ex.shutdownNow();
            }
        }catch(InterruptedException e){
            ex.shutdownNow();
        }

        System.out.println("main thread finished");

    }

メインスレッドが表示されます。スレッドによって実行された内容は、次の場所に出力されます。この方法は、方法 1 と同様に待機時間を設定する必要がありますが、完璧な方法ではありません。

方法 3 thread.join

thread は、次のことを意味します。このコードを実行しているスレッドは一時停止状態になり、このメソッドを呼び出しているスレッド (ここではこのスレッド) が実行を終了するのを待ってから実行を続行します。次の例では、子スレッドはすべて

main

にあります。はスレッドの上に作成されるため、

main

スレッドで

特定の sub-thread.join

を実行すると、サブスレッドの実行が終了するまで待機してから

main thread のコードは次のとおりです:

pool-1-thread-1finished
pool-1-thread-5finished
pool-1-thread-4finished
pool-1-thread-9finished
pool-1-thread-8finished
pool-1-thread-3finished
pool-1-thread-2finished
pool-1-thread-7finished
pool-1-thread-6finished
pool-1-thread-10finished
main thread finished
実行結果:
public static void main(String[] args) throws InterruptedException{
        List<Thread> list = new ArrayList<>();        for(int i=0; i<10; i++){
            Thread t = new Thread("subthread" + i){
                @Override                public void run() {                    try{
                        Thread.sleep(3000);
                        System.out.println(Thread.currentThread().getName() + "finished");
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            };
            list.add(t);
            t.start();
        }        for(Thread item : list){
            item.join();
        }
        System.out.println("main thread finished");
    }
上記の 2 つの方法と比較して、この方法を使用する利点は、待機時間を設定します。メソッド 4 Thread.yield と Thread.activeCountまず、これら 2 つのメソッドの機能を説明します。 Thread.yield

わかりやすく言うと、これは次のことを意味します。このメソッドを呼び出す現在のスレッドは

放棄し、

CPU

を占有します。ただし、これは現在のスレッドが実行されなくなるわけではありません。 #Thread.activeCount

メソッドは、現在の呼び出しスレッドに対応するスレッド グループ内のアクティブなスレッドの数を返します。 スレッド (新しいスレッド) を作成する場合、

ThreadGroup

パラメータは、現在の呼び出しスレッドに対応するスレッド グループを参照します。このパラメータが指定されていない場合、作成されるスレッドは、このスレッドを作成したスレッドと同じスレッド グループになります。コードは次のとおりです。 :

subthread1finished
subthread2finished
subthread0finished
subthread3finished
subthread6finished
subthread5finished
subthread4finished
subthread9finished
subthread7finished
subthread8finished
main thread finished
実行結果:
public static void main(String[] args) {        // 关键参数
        int defaultThreadNum = 2;        for(int i=0; i<10 ;i++){            new Thread("subthread" + i){
                @Override                public void run() {                    try {
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName() + "finished");
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }.start();
        }        while(Thread.activeCount() > defaultThreadNum){            // 当活跃线程数大于设定的默认线程数的时候 主线程让步
            Thread.yield();
        }
        System.out.println("main thread finished");
    }
非常に重要な点の 1 つは、thisdefaultthreadnum が 2 に設定されているということです。一部のブログではこれを 1 に設定していますが、1 では無限ループが発生し、メインスレッドが終了できなくなるのです。その理由は、除外した後は誰もがそう考えるからです。メイン スレッドが配置されているスレッド グループ内のサブスレッドは、実際には、次のコードを実行した場合には当てはまりません。
subthread0finished
subthread4finished
subthread1finished
subthread8finished
subthread9finished
subthread5finished
subthread2finished
subthread3finished
subthread6finished
subthread7finished
main thread finished
出力:
public static void main(String[] args) {
        Thread.currentThread().getThreadGroup().list();
    }
メイン スレッドが存在するスレッド グループに Monitor Ctrl-Break

という別のスレッドがあることがわかります。したがって、すべての子スレッドを除外した後でも、まだ 2 つのスレッドが存在します。

defaultThreadNum

を 2 に設定する必要があります。

このメソッドでも待ち時間を設定する必要はありません。要約すると、すべてのサブスレッドにメイン スレッドを実装する必要があります。再度実行する前に、方法 3 と方法 4 を使用できます。

関連する推奨事項:

Java スレッド マルチスレッドの包括的な分析

php5非 - スレッドセーフとスレッドセーフの違い

以上がすべてのサブスレッドのタスクが完了した後にメインスレッドをシャットダウンする 4 つの方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JVMはオペレーティングシステムAPIの違いをどのように処理しますか?JVMはオペレーティングシステムAPIの違いをどのように処理しますか?Apr 27, 2025 am 12:18 AM

JVMは、JavanativeInterface(JNI)およびJava Standard Libraryを介してオペレーティングシステムのAPIの違いを処理します。1。JNIでは、Javaコードがローカルコードを呼び出し、オペレーティングシステムAPIと直接対話できます。 2. Java Standard Libraryは統一されたAPIを提供します。これは、異なるオペレーティングシステムAPIに内部的にマッピングされ、コードがプラットフォーム間で実行されるようにします。

Java 9で導入されたモジュール性は、プラットフォームの独立性にどのように影響しますか?Java 9で導入されたモジュール性は、プラットフォームの独立性にどのように影響しますか?Apr 27, 2025 am 12:15 AM

modularitydoesnotdirectlyectlyectjava'splatformindepensence.java'splatformendepenceismaindainededainededainededaindainedaindained bythejvm、butmodularityinfluencesApplucationStructure andmanagement、間接的なインパクチャプラット形成依存性.1)

ByteCodeとは何ですか?また、Javaのプラットフォームの独立性とどのように関係していますか?ByteCodeとは何ですか?また、Javaのプラットフォームの独立性とどのように関係していますか?Apr 27, 2025 am 12:06 AM

bytecodeinjavaisthe intermediaterepresentationthateNablesplatformindepence.1)javacodeis compiledintobytecodestoredin.classfiles.2)thejvminterpretsorcompilesthisbytecodeintomachinecodeatime、

Javaがプラットフォームに依存しない言語と見なされるのはなぜですか?Javaがプラットフォームに依存しない言語と見なされるのはなぜですか?Apr 27, 2025 am 12:03 AM

javaachievesplatformedenceTheTheTheJavavirtualMachine(JVM)、これは、javacodeisisisisisissompiledIntobytecode.2)javaCodeisisisisissompiledevedevicetecode.2)

グラフィカルユーザーインターフェイス(GUI)は、Javaのプラットフォーム独立性の課題をどのように提示できますか?グラフィカルユーザーインターフェイス(GUI)は、Javaのプラットフォーム独立性の課題をどのように提示できますか?Apr 27, 2025 am 12:02 AM

Javagui開発におけるプラットフォームの独立性は課題に直面していますが、Swing、Javafx、統一外観、パフォーマンス最適化、サードパーティライブラリ、クロスプラットフォームテストを使用することで対処できます。 Javaguiの開発は、クロスプラットフォームの一貫性を提供することを目的としたAWTとSwingに依存していますが、実際の効果はオペレーティングシステムごとに異なります。ソリューションには以下が含まれます。1)SwingおよびJavafxをGUIツールキットとして使用します。 2)uimanager.setlookandfeel()を介して外観を統合します。 3)さまざまなプラットフォームに合わせてパフォーマンスを最適化します。 4)ApachepivotやSWTなどのサードパーティライブラリを使用する。 5)一貫性を確保するために、クロスプラットフォームテストを実施します。

Java開発のどの側面がプラットフォームに依存していますか?Java開発のどの側面がプラットフォームに依存していますか?Apr 26, 2025 am 12:19 AM

javadevelopmentisnotentirelylylypratform-IndopentDuetoseveralfactors.1)jvmvariationsaffectperformanceandbehavioracrossdifferentos.2)nativeLibrariesviajniintroducePlatform-specificissues.3)giaiasystemsdifferbeTioneplateplatifflics.4)

さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?Apr 26, 2025 am 12:15 AM

Javaコードは、さまざまなプラットフォームで実行するときにパフォーマンスの違いがあります。 1)JVMの実装と最適化戦略は、OracleJDKやOpenJDKなどとは異なります。 2)メモリ管理やスレッドスケジューリングなどのオペレーティングシステムの特性もパフォーマンスに影響します。 3)適切なJVMを選択し、JVMパラメーターとコード最適化を調整することにより、パフォーマンスを改善できます。

Javaのプラットフォームの独立性の制限は何ですか?Javaのプラットフォームの独立性の制限は何ですか?Apr 26, 2025 am 12:10 AM

java'splatformindepentedencehaslimitationsincludingporformanceoverhead、versioncompatibulisisues、changleSwithnativeLibraryIntegration、プラットフォーム固有の機能、およびjvminStallation/maintenation。

See all articles

ホット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衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!