• java多线程16:join()的使用


    讲解join()方法之前请确保对于即wait()/notify()/notifyAll()机制已熟练掌握。可以参考前面的笔记

    join()方法的作用是等待线程销毁。join()方法反应的是一个很现实的问题,比如main线程的执行时间是1s,子线程的执行时间是10s,但是主线程依赖子线程执行完的结果,这时怎么办?可以像生产者/消费者模型一样,搞一个缓冲区,子线程执行完把数据放在缓冲区中,通知main线程,main线程去拿,这样就不会浪费main线程的时间了。另外一种方法,就是join()了。


    join()方法之前的铺垫





    上面的主线程想等待子线程,但是主线程先打印了,如果要实现主线程等待呢



    用join()来解决




    使用join成功的让主线程等待了,其实join内部还是使用的等待,所以join是放锁的




    join()方法与异常


    上面是ThreadB 调用a.join(),其实根据join的源码是当前B线程锁a线程对象,wait之后,B线程等待A线程notify,而要interrupt B线程就会出现异常,但是A线程还是继续,A线程是不受影响的




    join(long)方法的使用



    通过上面代码可以发现 join(long)  和 sleep(long)实现的效果是一样

    join()方法的一个重点是要区分出和sleep()方法的区别。join(2000)也是可以的,表示调用join()方法所在的线程最多等待2000ms,两者的区别在于:

    sleep(2000)不释放锁,join(2000)释放锁,因为join()方法内部使用的是wait(),因此会释放锁。看一下join(2000)的源码就知道了,join()其实和join(2000)一样,无非是join(0)而已:

      public final synchronized void join(long millis) 
          throws InterruptedException {
          long base = System.currentTimeMillis();
          long now = 0;
          if (millis < 0) {
                  throw new IllegalArgumentException("timeout value is negative");
         }
          if (millis == 0) {
             while (isAlive()) {
             wait(0);
             }
         } else {
             while (isAlive()) {
             long delay = millis - now;
             if (delay <= 0) {
                 break;
             }
             wait(delay);
             now = System.currentTimeMillis() - base;
             }
         }
         }

    第12行、第20行应该已经很清楚了

    而sleep是不会释放锁的




    sleep(long)方法不放锁



    上面的例子都证明了  join 是放锁的,而sleep是不会放锁的

    下面例子证明了join的另一种问题,原因是join是wait实现的,被其它线程唤醒后,会抢锁,而且是优先抢到锁





    方法join()之后的代码提前运行-----出现意外



    解释意外的发生情况





    可以清楚的看到,出现的情况是多种多样的,原因就在于join会抢锁,执行完毕之后,就放锁然后执行锁之后的代码,也是由于线程的随机性,情况多种多样,join不是每次都会抢到锁






  • 相关阅读:
    正则表达式语法介绍
    关系型数据库和非关系型数据库的简单对比
    lambda函数
    java基础系列--Exception异常处理
    springBoot基础系列--properties配置
    spring基础系列--JavaConfig配置
    java基础系列--Calendar类
    java基础系列--Date类
    一个特殊的List去重问题的解决方案
    Java学习笔记
  • 原文地址:https://www.cnblogs.com/signheart/p/6606532.html
Copyright © 2020-2023  润新知