166

このコードで、2 つの join と break は何を意味するのでしょうか? t1.join()終了するt2までt1停止しますか?

Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread t2 = new Thread(new EventThread("e2"));
t2.start();
while (true) {
   try {
      t1.join();
      t2.join();
      break;
   } catch (InterruptedException e) {
      e.printStackTrace();
   }
}
4

11 に答える 11

335

このスレッド参加コードは何を意味していますか?

Thread.join()メソッド javadocsから引用するには:

join()このスレッドが終了するのを待ちます。

おそらくメインスレッドであるサンプルコードを実行しているスレッドがあります。

  1. メイン スレッドは、 および スレッドを作成して開始しt1ますt2。2 つのスレッドが並行して実行を開始します。
  2. メイン スレッドはt1.join()、スレッドの終了を待機するために呼び出しt1ます。
  3. t1スレッドが完了し、メソッドt1.join()がメイン スレッドに戻ります。t1呼び出しが行われる前に既に終了している可能性があることに注意してください。そのjoin()場合、join()呼び出しはすぐに返されます。
  4. メイン スレッドはt2.join()、スレッドの終了を待機するために呼び出しt2ます。
  5. t2スレッドが完了し (または、スレッドが完了する前に完了した可能性がありますt1)、t2.join()メソッドがメイン スレッドに戻ります。

t1スレッドとスレッドは並行しt2て実行されていますが、それらを開始したメイン スレッドは、続行する前にそれらが終了するまで待機する必要があることを理解することが重要です。よくあるパターンです。また、および/またはメインスレッドがそれらを呼び出すに終了している可能性があります。その場合は待機せず、すぐに戻ります。t1t2join()join()

t1.join()は、t1 が終了するまで t2 を停止させることを意味しますか?

いいえ。呼び出しているメインt1.join()スレッドは実行を停止し、t1スレッドが終了するのを待ちます。t2スレッドは並行して実行されておりt1t1.join()呼び出しの影響を受けません。

try/catch に関して言えば、join()スローInterruptedExceptionは、呼び出しているメイン スレッドjoin()自体が別のスレッドによって中断される可能性があることを意味します。

while (true) {

結合をwhileループにするのは奇妙なパターンです。通常、最初の結合を行い、次に 2 番目の結合をInterruptedExceptionそれぞれの場合に適切に処理します。それらをループに入れる必要はありません。

于 2013-04-11T18:35:21.043 に答える
75

これはJava 面接でよく聞かれる質問です。

Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread e2 = new Thread(new EventThread("e2"));
t2.start();

while (true) {
    try {
        t1.join(); // 1
        t2.join(); // 2  These lines (1,2) are in in public static void main
        break;
    }
}

t1.join()つまり、t1 は「最初に終了したい」のようなことを言います。の場合も同様t2です。誰が開始t1またはt2スレッド (この場合はメソッド) に関係なく、main はタスクを完了するmainまで待機して終了します。t1t2

ただし、注意すべき重要な点は、 および の join 呼び出しシーケンスに関係なく、および 自身t1t2並行して実行できることです。待たなければならないのはスレッドです。t1t2main/daemon

于 2013-04-11T18:38:35.087 に答える
52

join()スレッドが完了するのを待つことを意味します。これはブロッカー メソッドです。メインスレッド ( を実行するスレッド) は、作業が終了するまでjoin()待機し、に対して同じことを行います。t1.join()t1t2.join()

于 2013-04-11T18:37:18.037 に答える
12

スレッド tA が tB.join() を呼び出すと、その原因は tB が終了するか tA 自体が中断されるのを待つだけでなく、tB の最後のステートメントと tA スレッドの tB.join() の後の次のステートメントとの間に事前発生関係を作成します。

スレッド内のすべてのアクションは、他のスレッドがそのスレッドの join() から正常に戻る前に発生します。

プログラムという意味です

class App {
    // shared, not synchronized variable = bad practice
    static int sharedVar = 0;
    public static void main(String[] args) throws Exception {
        Thread threadB = new Thread(() -> {sharedVar = 1;});
        threadB.start();
        threadB.join();

        while (true) 
            System.out.print(sharedVar);
    }
}

常に印刷

>> 1111111111111111111111111 ...

しかし、プログラム

class App {
    // shared, not synchronized variable = bad practice
    static int sharedVar = 0;
    public static void main(String[] args) throws Exception {
        Thread threadB = new Thread(() -> {sharedVar = 1;});
        threadB.start();
        // threadB.join();  COMMENT JOIN

        while (true)
            System.out.print(sharedVar);
    }
}

だけでなく、印刷することができます

>> 0000000000 ... 000000111111111111111111111111 ...

しかし

>> 00000000000000000000000000000000000000000000 ... 

常に「0」のみ。

Java メモリ モデルでは、「sharedVar」の新しい値をスレッド B からメイン スレッドに heppens-before 関係 (スレッド開始、スレッド結合、「synchonized」キーワードの使用、AtomicXXX 変数の使用など) なしで「転送」する必要がないためです。

于 2016-07-13T14:51:32.850 に答える
-3

メインスレッドがスレッド t1 と t2 を開始するとします。ここで、t1.join() が呼び出されると、メイン スレッドはスレッド t1 が終了するまで一時停止し、その後再開します。同様に、t2.join() が実行されると、メイン スレッドは、スレッド t2 が終了するまで再び一時停止し、その後再開します。

だから、これはそれがどのように機能するかです。

また、ここでは while ループは実際には必要ありませんでした。

于 2018-04-05T07:13:33.023 に答える