前言
在Java中,主线程和子线程是并行运行的,这意味着它们可以同时执行。然而,有时候我们需要在子线程执行完毕后,主线程才能继续执行。这时,我们可以使用线程的join()方法来实现主线程等待子线程运行完成再执行,这个在面试中,如果问到线程相关的知识,这个也是必问,本文就来讲解Thread的join方法,如何让主线程等待子线程运行完在执行。
一、join()方法的使用
join()方法是一个线程类的方法,用于等待当前线程终止。当调用join()方法时,当前线程将被挂起,直到被等待的线程终止。例如,
join()方法的原理就是:
将指定的Thread实例对象作为锁对象,在其上进行同步,只要那个线程还活着,那么就会持续等待(或者有限时长)线程终止之后会调用自身this.notifyAll,以通知在其上等待的线程。简单说,只要他活着大家就都等着, 他死了会通知,所以效果就是在哪里调用了谁的join,哪里就要等待这个线程结束,才能继续。
join有三个方法,实际调用wait方法
代码语言:java复制thread.join();
代码语言:java复制public final native void wait(long timeout) throws InterruptedException;
join()方法还有一个重载版本,可以接受一个超时时间参数,该参数表示主线程等待子线程的最长时间。如果子线程在超时时间内没有完成执行,主线程将继续执行。
代码语言:java复制thread.join(100);
thread.join(1000,10);
二、join()案例代码
上面介绍,join的用法,接来直接用代码演示。首先创建了一个子线程,然后启动它。接着,我们在主线程中调用子线程的join()方法,这将导致主线程等待子线程执行完毕。在子线程执行完毕后,主线程将继续执行。
代码语言:java复制package com.multi.thread.join;
public class TestJoin {
public static void main(String[] args) {
Object lock = new Object();
//开启一个子线程
Thread thread = new Thread(() -> {
for (int i = 0; i < 5; i ) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() " : working" ":" Thread.currentThread().getState());
}
});
thread.setName("t1");
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(thread.getState());
System.out.println(Thread.currentThread().getName() ":main end:" Thread.currentThread().getState());
}
}
点击thread.join()可以看到join源码,底层调用的还是wait方法
上面join类似自定义的wait()方法,不过不建议使用,因为join方法会判断线程是否isAlive,将当前线程对象thread作为锁对象。
代码语言:javascript复制synchronized (thread) {
try {
thread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
thread.wait()表示对当前方法(main)线程进行阻塞(block),导致主线程会等待thread线程唤醒通过jps命令查看java运行线程,jstack 线程id,可以看到主线程main的状态是WAITING
总结
本文介绍了如何实现主线程等待子线程运行完成再执行的方法,通过线程的join()方法来实现。join()方法可以使主线程等待子线程执行完成,然后继续执行主线程。在实际开发中,我们可以使用join()方法来实现线程间的通信。
我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!