javaスレッドjoinの使い方について話します。


このブログの紹介では、javaスレッドのjoin方法を紹介します。join方法はスレッド同期を実現し、元々並列に実行されていたマルチスレッド方法をシリアルに変えて実行することができます。
図に示すコードのように、並列に実行されます。

public class ThreadTest {
  //private static final Long count = 10000L;
  public static void main(String[] args){
    long base = System.currentTimeMillis();
    try {
      ThreadJoin t1 = new ThreadJoin("  1");
      ThreadJoin t2 = new ThreadJoin("  2");
      //t1.join();
      t1.start();
      t1.join();
      t2.start();

    } catch (Exception e) {
      e.printStackTrace();
    }
    long time = System.currentTimeMillis() - base;
    System.out.println("    :"+time);
  }
  
}
class ThreadJoin extends Thread{
  private static final Long count = 10L;

  public ThreadJoin(String name){
    super(name);
  }

  @Override
  public void run() {
    //super.run();
    for(int i = 1; i <= count; i ++){
      System.out.println(this.getName()+":"+i);
    }
  }
}
プリントした情報は全部このようです。
実行時間:0
スレッド1:1
スレッド2:1
スレッド2:2
スレッド2:3
スレッド2:4
スレッド2:5
スレッド2:6
スレッド2:7
スレッド2:8
スレッド2:9
スレッド2:10
スレッド1:2
スレッド1:3
スレッド1:4
スレッド1:5
スレッド1:6
スレッド1:7
スレッド1:8
スレッド1:9
スレッド1:10
シリアル実行を行うには、ジョイン方法を加えて、スレッド1の実行が完了してからスレッド2、つまりシリアル実行を開始することができます。

public class ThreadTest {
  //private static final Long count = 10000L;
  public static void main(String[] args){
    long base = System.currentTimeMillis();
    try {
      ThreadJoin t1 = new ThreadJoin("  1");
      ThreadJoin t2 = new ThreadJoin("  2");
      //t1.join();
      t1.start();
      t1.join();
      t2.start();

    } catch (Exception e) {
      e.printStackTrace();
    }
    long time = System.currentTimeMillis() - base;
    System.out.println("    :"+time);
  }
  
}
class ThreadJoin extends Thread{
  private static final Long count = 10L;

  public ThreadJoin(String name){
    super(name);
  }

  @Override
  public void run() {
    //super.run();
    for(int i = 1; i <= count; i ++){
      System.out.println(this.getName()+":"+i);
    }
  }
}
スレッド1:1
スレッド1:2
スレッド1:3
スレッド1:4
スレッド1:5
スレッド1:6
スレッド1:7
スレッド1:8
スレッド1:9
スレッド1:10
実行時間:0
スレッド2:1
スレッド2:2
スレッド2:3
スレッド2:4
スレッド2:5
スレッド2:6
スレッド2:7
スレッド2:8
スレッド2:9
スレッド2:10
実行結果から見ると、既にシリアル実行スレッドです。
上記の例は現場1のjoin方法を調整したもので、つまりスレッド1を先に実行してからメインスレッドを実行します。
joinメソッドの役割は、例を挙げて、BスレッドのjoinメソッドをAスレッドで調整する場合、先にBスレッドを実行してから、Aスレッドを実行します。
ok、上記のジョインメソッドはパラメータを加えず、スレッドA.join(10)などのパラメータを加えても良いです。つまりスレッドAは10 sを実行した後、Bスレッドを実行し続けるということです。
注意:join時間パラメータがデフォルトの場合、デフォルトは0、すなわちjoin()はjoin(0)と同じです。

/**
   * Waits for this thread to die.
   *
   * <p> An invocation of this method behaves in exactly the same
   * way as the invocation
   *
   * <blockquote>
   * {@linkplain #join(long) join}{@code (0)}
   * </blockquote>
   *
   * @throws InterruptedException
   *     if any thread has interrupted the current thread. The
   *     <i>interrupted status</i> of the current thread is
   *     cleared when this exception is thrown.
   */
  public final void join() throws InterruptedException {
    join(0);
  }
Threadのソースコードは、デフォルトの割り当てが0であることが分かります。そして、この0はどういう意味ですか?0は0 sを実行するという意味ではなく、Aスレッドを実行してからBスレッドを実行するという意味です。
ok、そしてなぜジョインメソッドを呼び出したらスレッド同期が可能ですか?コードを簡単に見ます。

public final synchronized void join(long millis)
  throws InterruptedException {
    long base = System.currentTimeMillis();
    long now = 0;
 //         
    if (millis < 0) {
      throw new IllegalArgumentException("timeout value is negative");
    }
 //     0      
    if (millis == 0) {
      while (isAlive()) {//         
        wait(0);//     wait  
      }
    } else {//      0   
      while (isAlive()) {
        long delay = millis - now;//        
        if (delay <= 0) {
          break;
        }
        wait(delay);//       wait  
        now = System.currentTimeMillis() - base;
      }
    }
  }
ソースを見ても分かりやすいです。現場のwaitメソッドを呼び出してスレッド同期を実現しました。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。