前書き
マルチスレッドプログラミングでは、あるスレッドの実行が別のスレッドの実行結果に依存する場合があります。JDKは、この機能を実現するための結合メソッドを提供します。
スレッドでjoinメソッドを呼び出すと、呼び出し元のスレッドは待機状態になります。参照されるスレッドの実行が完了するまで、待機状態のままになります。
結合とそのオーバーロードメソッド:
- join()、スレッド実行の終了を待ちます。
- join(long millis)は、join()メソッドに似ていますが、スレッドの実行を待機する最大ミリ秒数を示す追加のミリ秒パラメーターがあります。join(0)はjoin()と同等です。
- join(long millis、int nanos)は、待機時間がより正確であることを除いて、join(long millis)メソッドと同じです。
結合メソッドの基本的な使用法
子スレッドの終了を待って、メインスレッドは実行を継続します。
// java项目www.fhadmin.orgpublic class Demo { public static void main(String [] args)throws InterruptedException { Thread thread = new Thread(()-> { try { Thread.sleep(3000); } catch(InterruptedException e){ e.printStackTrace(); } System.out.println( "数ダウンロード加取中..."); }); thread.start(); thread.join(); System.out.println( "データ加加完毕"); } }
出力結果:
データの読み込み... データの読み込みが完了しました
最大待機時間を設定します。この時間の後、子スレッドの実行が終了するのを待つのではなく、メインスレッドが実行を継続します。
// java项目www.fhadmin.orgpublic class Demo { public static void main(String [] args)throws InterruptedException { Thread thread = new Thread(()-> { try { Thread.sleep(3000); } catch(InterruptedException e){ e.printStackTrace(); } System.out.println( "数ダウンロード加取中..."); }); thread.start(); thread.join(1000); System.out.println( "データ加加完毕"); } }
出力結果:
データの読み込みが完了しました データの読み込み...
結合メソッドのソースコード
joinメソッドのソースコードは次のとおりです。
// javaプロジェクトwww.fhadmin.orgpublic final synchronized void join(long millis)throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; //待機時間が0未満の場合、IllegalArgumentExceptionを直接スローし ます。 (millis <0){ throw new IllegalArgumentException( "timeout value isnegative "); } //待機時間は0で、wait(0)を呼び出し、スレッドが終了するのを待ちます。(join(0)はwait(0)の呼び出しと同じです) if(millis == 0){ while(isAlive()){ wait(0); } } else { //待機中時間は0より大きいですが、途中で起きても、待機時間を超えない限り、待機状態になります。 while(isAlive()){ long delay = mills-now; if(delay <= 0){ break; } wait(delay); now = System.currentTimeMillis()-ベース; } } }
joinメソッドのソースコードから、joinメソッドの本質はスレッドオブジェクトのwaitメソッドを呼び出すことであることがわかります。joinメソッドを呼び出すときは、スレッドオブジェクトのロックを取得してから取得する必要があります。スレッドオブジェクトのwaitメソッドが呼び出されます。スレッドが終了すると、スレッドオブジェクトが自動的に呼び出されます。notifyAllメソッド。
したがって、同期を行うときは、スレッドオブジェクトをロックオブジェクトとして使用しないようにする必要があります。これは、システムAPIの動作に影響を与える可能性があるためです。