简简单单聊一下多线程的join()方法

码农在囧途

不可否认的是,在这个圆滑当道的时代,如果一个人太过于正直,刚正不阿,那么可能会四处碰壁,而那些世故的机会主义往往如鱼得水,我们面对 这样一个社会规则,我觉得我们可以适当收起自己的锐利,做到知圆滑而不圆滑,知世故而不世故,应该保持一颗年轻的心态,而不是随着年龄的增长 而变得油腻,圆滑,世故。

join()使用场景

当一个方法中调用了多个接口时,为了提升效率,我们通常会使用多线程进行异步调用,不过有一些场景我们需要对某几个接口的值进行汇总,然后再去调用其他的接口, 我们在统计一些报表时,往往会进行大量的运算,调用,然而它们之间会存在依赖,所以我们就需要使用相应的机制来保证执行的顺序,实现方式有很多,Java中我们可以 使用join(),闭锁CountDownLatch(),信号量Semaphore()等,今天我们先从基础的join()说起。

比如调用Rpc接口Api1和Api2成功后,我们用这两个接口的返回值进行处理,然后去调用Api5,那么此时我们就需要在调用Api5之前确保Api1和Api2执行完成。
简简单单聊一下多线程的join()方法

如上图,Api1和Api2执行完成后再轮到Api5执行,那么我们就可以使用join()方法来做。

join()示例

使用join()后,会阻塞使用join的线程,直到任务执行完成后才会返回,如下,主线程启动了线程1和线程2后,使用了join()将两个线程进行阻塞,等待thread1和thread2 执行完任务后才继续往下执行doIt()方法。

public class ThreadOfJoinTest {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new Runnable() {
@SneakyThrows
@Override
public void run() {
Thread.sleep(2000);
System.out.println("线程1执行完毕");
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程2执行完毕");
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
doIt();
}

public static void doIt(){
System.out.println("线程1和线程2执行完成后才到我执行");
}
}

输出

线程2执行完毕
线程1执行完毕
线程1和线程2执行完成后才到我执行

从上面的输出可以看出线程使用join()可以阻塞线程,直到任务完成后才会向下执行。

join源码分析

调用join(millis)或join()后,首先会获取当前的时间戳base,如果传递过来的时间参数millis为0并且线程处于存活状态,那么线程将会一直挂起,直到任务完成, 如果millis大于0,就会计算出线程挂起的时间,然后循环判断挂起的时间当挂起的时间<=0,那么代表当前线程任务已经完成,结束挂起,join()里面挂起线程使用的 是Object中的await()方法。

public class Thread implements Runnable{
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");
}
//传过来的时间参数如果为0
if (millis == 0) {
//如果线程还是存活状态,那么将会一直挂起
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
//delay时延迟时间
long delay = millis - now;
//延迟时间小于0,则证明线程结束挂起
if (delay <= 0) {
break;
}
//线程挂起
wait(delay);
//计算时间间隔
now = System.currentTimeMillis() - base;
}
}
}
}

今天的分享就到这里,感谢你观看,下期见。


原文始发于微信公众号(刘牌):简简单单聊一下多线程的join()方法

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/150764.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!