join为啥会阻塞主线程?
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】边叫边练。
join为啥会阻塞主线程?的更多相关文章
- 关于ViewPager设置属性页setCurrentItem会阻塞主线程ANR总结
关于android开发设置View Pager的直接跳转页set CurrentItem会阻塞主线程ANR. 根据网上解决的说法,分析源码: if (mFirstLayout) { // We don ...
- Kafka producer异步发送在某些情况会阻塞主线程,使用时候慎重
最近发现一个Kafka producer异步发送在某些情况会阻塞主线程,后来在排查解决问题过程中发现这可以算是Kafka的一个说明不恰当的地方. 问题说明 在很多场景下我们会使用异步方式来发送Kafk ...
- C# 多线程join的用法,等待多个子线程结束后再执行主线程
等待多个子线程结束后再执行主线程 class MultiThread{ #region join test public void MultiThreadTest() { Thread[] ths = ...
- python 之 并发编程(进程池与线程池、同步异步阻塞非阻塞、线程queue)
9.11 进程池与线程池 池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务 池子内什么时候装进程:并发的任务属于计算密集型 池子内什么时候装线程:并发的任务属于I ...
- C#新开一个线程取到数据,如何更新到主线程UI上面
一:问题 之前有被面试官问过,在WinForm中,要去网络上获取数据,由于网络环境等原因,不能很快的完成,因此会发生进程阻塞,造成主进程假死的现象,需要怎么解决? 二:思路 因此,往往是新 ...
- AnimateWindow 阻塞当前线程问题
今天查了蛮多的,虽然不是系统的学习,收获也不小.下面说一下我的解决方法: 问题一:采用 AnimateWindow API实现消息窗体FormMsg的动画出现,但由于该方法会阻塞当前线程,造成其他窗体 ...
- [置顶] 使用严苛模式打破Android4.0以上平台应用中UI主线程的“独断专行”
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 已经有好一段时间没有关注Android应用方面的事情了:)最近单位来了一个Androi ...
- Qt中运行后台线程不阻塞UI线程的方案
有一个想法,一个客户端,有GUI界面的同时也要向网络服务器发送本地采集的数据,通过网络发送数据的接口是同步阻塞的,需要等待服务器响应数据. 如果不采用后台线程的方案,用主UI线程关联一个定时器QTim ...
- 千万别在UI线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死
原文地址:https://www.cnblogs.com/wangchuang/archive/2013/02/20/2918858.html .c# Invoke和BeginInvoke 区别 Co ...
随机推荐
- 2019 ccpc秦皇岛
1006 (dfs) #include <bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; const dou ...
- hdu5884 Sort(二分)
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- Codeforces Round #533 (Div. 2) C. Ayoub and Lost Array(递推)
题意: 长为 n,由 l ~ r 中的数组成,其和模 3 为 0 的数组数目. 思路: dp[ i ][ j ] 为长为 i,模 3 为 j 的数组数目. #include <bits/stdc ...
- P1108 低价购买(DP)
题目描述 "低价购买"这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:"低价购买:再低价购买".每次你购买一支股 ...
- P1020 导弹拦截(LIS)
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- hdu3564 Another LIS
Problem Description There is a sequence firstly empty. We begin to add number from 1 to N to the seq ...
- Codeforces Round #479 (Div. 3) F. Consecutive Subsequence (DP)
题意:给你一个长度为\(n\)的序列,求一个最长的\({x,x+1,x+2,.....,x+k-1}\)的序列,输出它的长度以及每个数在原序列的位置. 题解:因为这题有个限定条件,最长序列是公差为\( ...
- 同时拿到BATJMD的Offer是怎样的一种体验?
写在前面 又到了收割Offer的季节,你准备好了吗?曾经的我,横扫各个大厂的Offer.还是那句话:进大厂临时抱佛脚是肯定不行的,一定要注重平时的总结和积累,多思考,多积累,多总结,多复盘,将工作经历 ...
- codeforces 1016C - Vasya And The Mushrooms 【构造 + 思维】
题目链接:戳这里 题意:从(1,1)出发,一遍把格子走完,每个格子只能走一次.问怎么走总和最大. 解题思路:画图可知,总共就3种走法的混合. dw: 样例1的走法 up: 样例1反过来的走法 lp: ...
- 自己yy的中缀表达式转后缀表达式(未验证完全正确)
目前自己测试的表达式都没有出过问题 思路是这样,先将后缀表达式的计算顺序搞出来..当完全缩出来一个数的时候,如果后面还有要计算的,我们就把它放到后缀表达式的后面 先算后面的..不断迭代.. #incl ...