介绍

使用 Thread 的 join 方法来实现等待机制,当被等待的线程执行完成,等待线程再继续执行。
可以看到,join使用了内部锁,join方法是在等待线程中被调用的,所以等待线程获取了该对象锁,然后调用 wait() 进入了等待。
image.png
这个 wait 方法,当传入的值大于 0 时,在时间结束后自动唤醒,当传入 0时,直到被 notify / notifyAll 唤醒才可以结束阻塞。没在 wait(long)中找到相关注释,到是在 wait(long , int)中找到了
image.png
以上是阻塞,那么 join 如何实现唤醒呢?源码在 jvm 中,大概是当所在的线程结束后,会调用 notifyAll() 将所有等待该对象锁的线程全部唤醒。自然主线程就被唤醒了,然后检测到被等待的线程已经结束,然后就退出了循环,就被唤醒了,等待线程可以继续执行了。具体可以看这篇博客 https://segmentfault.com/a/1190000017255019

使用

简单实现一个生活中的例子好了。前几天我去买正新鸡排,买一个鸡排送一杯饮料,在炸鸡排的同时,可以调制装配饮料,因此,可以将这两个操作并行,当两个操作执行完,进行包装完成售出。因此可以用 join() 实现以上行为

  1. package cn.zjm404.stu.thread.cooperation.wait.thread;
  2. public class ZhengXinChickenChopShop {
  3. private void getDrink(){
  4. System.out.println("配置饮料");
  5. }
  6. private void getChickenChop(){
  7. System.out.println("炸鸡排");
  8. }
  9. public void sellChickenChop() throws InterruptedException {
  10. Thread t1 = new Thread(()->{
  11. this.getChickenChop();
  12. });
  13. Thread t2 = new Thread(()->{
  14. this.getDrink();
  15. });
  16. t1.start();
  17. t2.start();
  18. t1.join();
  19. t2.join();
  20. System.out.println("打包,售出");
  21. }
  22. }
  1. package cn.zjm404.stu.thread.cooperation.wait.thread;
  2. public class Client {
  3. public static void main(String[] args) {
  4. ZhengXinChickenChopShop shop = new ZhengXinChickenChopShop();
  5. try {
  6. shop.sellChickenChop();
  7. } catch (InterruptedException e) {
  8. e.printStackTrace();
  9. }
  10. }
  11. }

参考