当主线程执行过快,而子线程需要耗费大量的执行时间,但是主线程执行时最后需要使用到子线程的一些结果,而主线程却比子线程先结束,那怎么去用到子线程的结果呐,这时Thread类的join方法就可实现满足上述条件的结果。
先说一下Thread.join()
在当前线程中调用另一个线程的join方法,当前线程进入阻塞状态,直到另一个线程运行结束,当前线程再由阻塞转为就绪
而join方法具体是怎么执行的呐
这里点开Thread类的join方法一步一步往下看即可
而代码里面的wait就是Object类里的wait()方法。
首先isAlive()方法,先判断当前线程是否处于活动状态(线程尚未终止的状态,即线程处于正在运行或开始运行的状态),为true则调用Object类的wait()方法。
Object.wait()使当前线程挂起,需要用notify/notifyAll来唤醒它,挂起线程后会释放锁。
这里值得注意的是join被synchronized修饰,因为obj.wait(),obj.notify()这些方法在运行时必须获取object对象锁,而object.wait()执行顺序就是
1.先获取到对象锁
2.拿到object监视器
3.调用object.wait()
4.释放监视器
5.释放锁
notify,notifAll()也同理,值得注意的是notify执行后线程不会立即去执行wait后的代码,而是等notify执行完后释放object监视器,释放锁之后重新获得后才会继续执行wait之后的代码。
下面看看Thread.join()的具体使用
先看不加join的。
public static void main(String[] args) {
logger.info(Thread.currentThread().getName()+"主线程运行开始");
Thread t1=new Thread(new Runnable1());
t1.start();
logger.info(Thread.currentThread().getName()+"主线程运行结束");
}
class Runnable1 implements Runnable{
protected Logger logger= LoggerFactory.getLogger(this.getClass());
private int i=0;
public void method1(){
i++;
}
@Override
public void run() {
logger.info(Thread.currentThread().getName()+"线程运行开始");
for (int j=0;j<100000;j++){
method1();
}
logger.info(Thread.currentThread().getName()+"线程运行结束");
}
}
因为在子线程里用了耗时的操作,可见主线程运行结束后子线程才开始运行。而在子线程启动后加入join可看到
主线程会等待子线程结束后结束。