目录

join使用

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

总结


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");//开启一个线程AthreadA.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");//开启一个线程AthreadA.start();//主线程会持有子线程的锁,子线程还没开始主线程就阻塞了,等待子线程结束后通知;threadA.join2(0);System.out.println(Thread.currentThread().getName()+ "线程执行");}private static class MyThread extends Thread {public MyThread(String name) {super(name);}@Overridepublic 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】边叫边练。

join为啥会阻塞主线程?相关推荐

  1. CompleteFuture的 join方法会阻塞主线程,使用小心

    今天发现一个关于CompleteFuture的疑问,按道理join方法会阻塞,但是发现并不会,参加如下: public static void main(String[] args) {Long to ...

  2. 阻塞主线程,等待异步子线程执行完毕再退出主线程,有几种写法?

    这里实际是考察线程间的通信,正常情况下,主线程里启动异步线程执行某个方法,理论上主线程和这个异步线程是并行执行,互不干扰,但是现在要求异步线程执行完毕方法之后,才能继续执行主线程,实际是如何阻塞主线程 ...

  3. android如何阻塞主线程,Android-Android如何避免阻塞主线程

    Android的Handler和AsyncTask,可以避免阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的. AsyncTask,它使创建需要与用户界面交互的长时间运 ...

  4. Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么

    面试官: Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么 心理分析:该问题很难被考到,但是如果一旦问到,100%会回答不上来.开发者很难注意到一个主线程的四循环居然没有阻塞住主线程 ...

  5. 腾讯Android面试:Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么

    面试官: Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么 心理分析:该问题很难被考到,但是如果一旦问到,100%会回答不上来.开发者很难注意到一个主线程的四循环居然没有阻塞住主线程 ...

  6. 使用ThreadPoolExecutor,当提交线程超过maximumPoolSize 会阻塞主线程吗?

    今天开会同事说使用线程池,当提交的子线程超过运行的最大线程数,会阻塞主线程,然后我就回复 有拒绝策略,会抛出异常,同时也要确认当线程池满的时候executor.execute方法会不会是阻塞的了,其实 ...

  7. “Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么?”

    前言 Android的消息机制主要是指Handler的运行机制,对于大家来说Handler已经是轻车熟路了,可是真的掌握了Handler?本文主要通过几个问题围绕着Handler展开深入并拓展的了解. ...

  8. Python多线程-阻塞主线程

    写在前面: 前面已经有Scala实现多线程了,那么用Python实现多线程又有什么区别和好处? Scala里实现多线程,启的是同一个Application,计算多线程任务的task都是同时返回到dri ...

  9. java定时器阻塞主线程_Java基础_死锁、线程组、定时器Timer

    一.死锁问题: 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不可能正常终止. 比如,线程一需要第一把所,此时锁处于空闲状态,给了 ...

最新文章

  1. FireFox 下通过 javascript 得到表单值
  2. 「BZOJ 2152」聪聪可可
  3. 一道泄露并遭禁用的谷歌面试题,背后玄机全解析
  4. linux的spio在服务器间,scp 将数据从一台linux服务器复制到另一台linux服务器
  5. java list 分组_Java 将List中的实体类按照某个字段进行分组并存
  6. Centos7:mysql5.6安装,配置及使用(RPM方式)
  7. Android WebView常见问题及解决方案汇总【很全很实用】
  8. mysql 参数调整_mysql需要调整的参数-阿里云开发者社区
  9. 个人站立会议第二阶段04
  10. 用python画四叶草-使用 python 操作 redis
  11. Conflux吐槽君:IOTA物联网电磁炉-让PoW的耗电没有遗憾
  12. request.getContextPath()
  13. C#如何查看DLL文件中的成员
  14. matlab拟合gamma分布,使用matlab拟合Gamma分布
  15. web前端学习(二十八)——CSS3下拉菜单的相关设置
  16. html调用网易云播放器无法自动播放,HTML网页调用 网易云 音乐播放器代码-Go语言中文社区...
  17. 网络扫描 : nbtscan
  18. 5款实用报表工具分析,报表工具这样选!
  19. 后端Java人必备:30个优化SQL的良心建议
  20. 计算机研究生院校全国排名2015,2018年武书连中国大学排行榜(完整版)_计算机考研院校...

热门文章

  1. [C++] [MinGW] MinGW下载与使用
  2. day43--插入排序
  3. 关于EDP触摸屏使用笔记
  4. 过节前的数据库系统检查
  5. 项目四 个人所得税计算器 switch语句
  6. 看看各省地图都像什么,笑趴了!
  7. 身份证二要素验证的使用场景介绍
  8. 轻量级的架构决策记录机制
  9. pkg打包node服务为双击可执行二进制文件Windows x64系统
  10. 怎么将翼型导入catia_catia与cfd的翼型设计