介绍
使用 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();}}}
