伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

join为啥会阻塞主线程?

来源:本站原创 浏览:94次 时间:2022-11-14
join使用

上篇我们介绍了CountDownLatch,顺便说到了Thread中的join方法!

import java.util.concurrent.TimeUnit;/** * @author :jiaolian * @date :Created in 2021-02-28 21:43 * @description:join测试 * @modified By: * 公众号:叫练 */public class JoinTest {    public static void main(String[] args) throws InterruptedException {        Thread threadA = new Thread(()->{            try {                TimeUnit.SECONDS.sleep(2);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName()+":想先执行");        },"线程A");        //开启一个线程A        threadA.start();        //主线程会持有子线程的锁,子线程还没开始主线程就阻塞了,等待子线程结束后通知;        threadA.join();        System.out.println(Thread.currentThread().getName()+ "线程执行");    }}

如上代码所示:在JoinTest开启一个线程A,threadA调用join()方法,主线程会等待threadA执行完毕!也就是两秒后,主线程执行最后一句话,运行结果如下图所示!

我们深入源码,join方法底层其实就是一个wait方法,但现在问题是:明明调用者是线程A,可阻塞的是mian线程,不应该阻塞的是threadA吗?


证明问题:明明调用者是线程A,可阻塞的是mian线程

我们参照Thread中join源码,将上面的代码改造如下:

import java.util.concurrent.TimeUnit;/** * @author :jiaolian * @date :Created in 2021-02-28 21:43 * @description:join测试 * @modified By: * 公众号:叫练 */public class JoinCodeTest {    public static void main(String[] args) throws InterruptedException {        MyThread threadA = new MyThread("线程A");        //开启一个线程A        threadA.start();        //主线程会持有子线程的锁,子线程还没开始主线程就阻塞了,等待子线程结束后通知;        threadA.join2(0);        System.out.println(Thread.currentThread().getName()+ "线程执行");    }    private static class MyThread extends Thread {        public MyThread(String name) {            super(name);        }        @Override        public void run() {            try {                TimeUnit.SECONDS.sleep(2);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getName()+":想先执行");        }        //复制Thread源码中的join方法测试阻塞的是线程A还是main线程?        public final synchronized void join2(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()) {                    //虽然调用者是线程A,但真正执行阻塞的是main线程!                    System.out.println(Thread.currentThread().getName()+"会阻塞");                    wait(0);                }            } else {                while (isAlive()) {                    long delay = millis - now;                    if (delay <= 0) {                        break;                    }                    wait(delay);                    now = System.currentTimeMillis() - base;                }            }        }    }}

如上代码所示:MyThread继承Thread,并复制了join源码,将join修改成join2,并在join2方法中增加了一个输出语句,System.out.println(Thread.currentThread().getName()+"会阻塞")用来测试阻塞的是线程A还是main线程,所以在JoinCodeTest的main方法中ThreadA是调用join2方法,

结果发现进入join2方法的线程是main线程。运行结果如下图所示!

这里可以把join理解成一个普通方法!真正阻塞的不是调用者线程,而是当前正在执行的线程。


总结

今天我们介绍了join方法,特别是将源码中代码copy出来证明测试,相信整理出来希望能对你有帮助,写的比不全,同时还有许多需要修正的地方,希望亲们加以指正和点评,喜欢的请点赞加关注哦。点关注,不迷路,我是【叫练】公众号,微信号【jiaolian123abc】边叫边练。




  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net