主线程创建并启动子线程,如果自线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束。如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据中的值,就要用到 join() 方法

先来看一个不用 join() 方法的例子

public class MyThread extends Thread {
 ​
     @Override
     public void run() {
         try {
             int secondVal = 2000;
             System.out.println(secondVal);
             Thread.sleep(secondVal);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     }
 ​
     public static void main(String[] args) {
         MyThread myThread = new MyThread();
         myThread.start();
         System.out.println("我想当 myThread 对象执行完毕之后我在执行");
         System.out.println("但上面代码中的 sleep 中的值应该写多少呢?");
         System.out.println("答案是:不能确定");
     }
 ​
 }

我想当 myThread 对象执行完毕之后我在执行但上面代码中的 sleep 中的值应该写多少呢?
答案是:不能确定
run...

从结果看到,主线程 Main 在子线程 Thread-0 执行完之前就已经执行结束了,如果我们想要让主线程 Main 在子线程 Thread-0 执行结束之后在执行,join() 就派上用场了

public class MyThread1 extends Thread {
 ​
     @Override
     public void run() {
         try {
             int time = 2000;
             System.out.println(Thread.currentThread().getName() + " 执行:"
                     + time / 1000 + "s");
             Thread.sleep(time);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     }
 ​
     public static void main(String[] args) throws InterruptedException {
         MyThread1 myThread1 = new MyThread1();
         myThread1.start();
         myThread1.join();
         System.out.println("我想当 myThread 对象执行完毕之后我在执行");
         System.out.println(System.currentTimeMillis());
     }
 }
 ​

Thread-0 执行:2s
我想当 myThread 对象执行完毕之后我在执行

从结果看到,线程 Thread-0,即子线程先执行了,而主线程 Main 在子线程执行完才执行。join() 方法使调用这个方法的线程 Thread-0 正常执行 run() 方法,而使 Thread-0 所在的线程 main 进行无限期的阻塞,等待线程 Thread-0 销毁后(执行完 run 方法后)再继续执行线程 main 后面的代码

因此,join() 方法使得调用该方法的那段代码所在的线程暂时阻塞