java线程join方法
java线程join方法
1.join方法
join方法的作用是进行线程插队,也就是说调用了join方法的线程相对于调用它的上级线程拥有跟高的执行权。调用join方法的线程的上级线程必须等待调用join方法的线程执行完成才能继续执行。
举个小例子:
public class testjoin{
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
Thread t1 = new Thread(new t1(),"t1");
t1.start();
}
}
class t1 implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"->"+i);
if(i==3) {
Thread t2 = new Thread(new t2(),"t2");
t2.start();
try {
t2.join(); //调用join方法,线程t1必须等待t2执行完毕才能继续执行。
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
class t2 implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++)
System.out.println(Thread.currentThread().getName()+"->"+i);
}
}
运行结果如下:
t1->0
t1->1
t1->2
t1->3
t2->0
t2->1
t2->2
t2->3
t2->4
t2->5
t2->6
t2->7
t2->8
t2->9
t1->4
t1->5
t1->6
t1->7
t1->8
t1->9
无论运行多少次,运行结果都不变,原因是t2线程运行了join方法,那么它的上级线程t1就必须等待t2运行完后才能继续调用。
2.join源码
join方法能传入一个常数,millis是要主线程暂停时间。
1.如果millis<0就抛出异常。
2.如果millis=0就判断当前调用join方法的线程是否存活。如果存活就不停地调用wait(0)方法。在一个实例Java对象上调用wait方法,那么当前线程就会从执行状态转变成等待状态,同时释放在实例对象上的锁,直到其它线程在刚才那个实例对象上调用notify方法并且释放实例对象上的锁,那么刚才那个当前线程才会再次获取实例对象锁并且继续执行。wait的作用是让“当前线程”等待,而这里的“当前线程”是指当前运行的线程。虽然是调用子线程的wait()方法,但是它是通过“主线程”去调用的;所以,休眠的是主线程,而不是“子线程”!
3.如果millis>0,先判断线程是否存活,然后调用wait方法。然后根据millis - now来调用wait方法,因为当调用t2.join时正在运行的是线程t1,所有主线程t1进入millis - now的阻塞状态,当时间超过millis - now毫秒是主线程将被唤醒。
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;
}
}
}
这里解释一下wait()和isAlive()方法的来源。
isAlive方法被native关键字标注了,表明了要调用其他语言进行协助。所以isAlive方法体不用Java来写,wait方法也如此
public final native boolean isAlive();
wait方法也被native关键字标注了,表明了要调用其他语言进行协助。
public final native void wait(long timeoutMillis) throws InterruptedException;
更多wait()方法的信息参考博客
https://blog.csdn.net/jiangzhexi/article/details/81152617.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)