join为啥会阻塞主线程?
目录
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为啥会阻塞主线程?相关推荐
- CompleteFuture的 join方法会阻塞主线程,使用小心
今天发现一个关于CompleteFuture的疑问,按道理join方法会阻塞,但是发现并不会,参加如下: public static void main(String[] args) {Long to ...
- 阻塞主线程,等待异步子线程执行完毕再退出主线程,有几种写法?
这里实际是考察线程间的通信,正常情况下,主线程里启动异步线程执行某个方法,理论上主线程和这个异步线程是并行执行,互不干扰,但是现在要求异步线程执行完毕方法之后,才能继续执行主线程,实际是如何阻塞主线程 ...
- android如何阻塞主线程,Android-Android如何避免阻塞主线程
Android的Handler和AsyncTask,可以避免阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的. AsyncTask,它使创建需要与用户界面交互的长时间运 ...
- Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么
面试官: Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么 心理分析:该问题很难被考到,但是如果一旦问到,100%会回答不上来.开发者很难注意到一个主线程的四循环居然没有阻塞住主线程 ...
- 腾讯Android面试:Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么
面试官: Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么 心理分析:该问题很难被考到,但是如果一旦问到,100%会回答不上来.开发者很难注意到一个主线程的四循环居然没有阻塞住主线程 ...
- 使用ThreadPoolExecutor,当提交线程超过maximumPoolSize 会阻塞主线程吗?
今天开会同事说使用线程池,当提交的子线程超过运行的最大线程数,会阻塞主线程,然后我就回复 有拒绝策略,会抛出异常,同时也要确认当线程池满的时候executor.execute方法会不会是阻塞的了,其实 ...
- “Handler中有Loop死循环,为什么没有阻塞主线程,原理是什么?”
前言 Android的消息机制主要是指Handler的运行机制,对于大家来说Handler已经是轻车熟路了,可是真的掌握了Handler?本文主要通过几个问题围绕着Handler展开深入并拓展的了解. ...
- Python多线程-阻塞主线程
写在前面: 前面已经有Scala实现多线程了,那么用Python实现多线程又有什么区别和好处? Scala里实现多线程,启的是同一个Application,计算多线程任务的task都是同时返回到dri ...
- java定时器阻塞主线程_Java基础_死锁、线程组、定时器Timer
一.死锁问题: 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不可能正常终止. 比如,线程一需要第一把所,此时锁处于空闲状态,给了 ...
最新文章
- FireFox 下通过 javascript 得到表单值
- 「BZOJ 2152」聪聪可可
- 一道泄露并遭禁用的谷歌面试题,背后玄机全解析
- linux的spio在服务器间,scp 将数据从一台linux服务器复制到另一台linux服务器
- java list 分组_Java 将List中的实体类按照某个字段进行分组并存
- Centos7:mysql5.6安装,配置及使用(RPM方式)
- Android WebView常见问题及解决方案汇总【很全很实用】
- mysql 参数调整_mysql需要调整的参数-阿里云开发者社区
- 个人站立会议第二阶段04
- 用python画四叶草-使用 python 操作 redis
- Conflux吐槽君:IOTA物联网电磁炉-让PoW的耗电没有遗憾
- request.getContextPath()
- C#如何查看DLL文件中的成员
- matlab拟合gamma分布,使用matlab拟合Gamma分布
- web前端学习(二十八)——CSS3下拉菜单的相关设置
- html调用网易云播放器无法自动播放,HTML网页调用 网易云 音乐播放器代码-Go语言中文社区...
- 网络扫描 : nbtscan
- 5款实用报表工具分析,报表工具这样选!
- 后端Java人必备:30个优化SQL的良心建议
- 计算机研究生院校全国排名2015,2018年武书连中国大学排行榜(完整版)_计算机考研院校...