介绍
使用 Thread 的 join 方法来实现等待机制,当被等待的线程执行完成,等待线程再继续执行。
可以看到,join使用了内部锁,join方法是在等待线程中被调用的,所以等待线程获取了该对象锁,然后调用 wait() 进入了等待。
这个 wait 方法,当传入的值大于 0 时,在时间结束后自动唤醒,当传入 0时,直到被 notify / notifyAll 唤醒才可以结束阻塞。没在 wait(long)中找到相关注释,到是在 wait(long , int)中找到了
以上是阻塞,那么 join 如何实现唤醒呢?源码在 jvm 中,大概是当所在的线程结束后,会调用 notifyAll() 将所有等待该对象锁的线程全部唤醒。自然主线程就被唤醒了,然后检测到被等待的线程已经结束,然后就退出了循环,就被唤醒了,等待线程可以继续执行了。具体可以看这篇博客 https://segmentfault.com/a/1190000017255019
使用
简单实现一个生活中的例子好了。前几天我去买正新鸡排,买一个鸡排送一杯饮料,在炸鸡排的同时,可以调制装配饮料,因此,可以将这两个操作并行,当两个操作执行完,进行包装完成售出。因此可以用 join() 实现以上行为
package cn.zjm404.stu.thread.cooperation.wait.thread;
public class ZhengXinChickenChopShop {
private void getDrink(){
System.out.println("配置饮料");
}
private void getChickenChop(){
System.out.println("炸鸡排");
}
public void sellChickenChop() throws InterruptedException {
Thread t1 = new Thread(()->{
this.getChickenChop();
});
Thread t2 = new Thread(()->{
this.getDrink();
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("打包,售出");
}
}
package cn.zjm404.stu.thread.cooperation.wait.thread;
public class Client {
public static void main(String[] args) {
ZhengXinChickenChopShop shop = new ZhengXinChickenChopShop();
try {
shop.sellChickenChop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}