温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中join有什么用

发布时间:2021-12-14 16:12:14 阅读:306 作者:小新 栏目:开发技术
Java开发者专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

小编给大家分享一下Java中join有什么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

java多线程里的join,从字面意思来看是联合,合并的意思,但如果面试时这么回答,基本上可以断定面试者还没搞懂。join究竟能干什么,今天给出一个最通俗的解释,那就是在多线程环境下实现暂时以单线程执行,或者说在并行执行的环境中实现暂时以串行执行。为了说明这个问题,我们看一段再常见不过的代码,代码内容是,让三个线程分布去打印一段内容

//代码块1public class TestJoin {    public static void main(String[] args) throws InterruptedException {        Thread t1 = new Thread(new DoSth());        Thread t2 = new Thread(new DoSth());        Thread t3 = new Thread(new DoSth());        t1.start();        t2.start();        t3.start();        System.out.println("主线程执行");    }}class DoSth implements Runnable {    @Override    public void run() {        int n = 
5;        while (n > 
0) {            System.out.println(Thread.currentThread().getName());            try {                Thread.sleep(1);            } catch (InterruptedException e) {                e.printStackTrace();            }            n--;        }    }}

执行结果如下:

线程1执行线程2执行线程3执行线程2执行线程3执行线程1执行线程2执行线程3执行线程2执行线程3执行线程2执行线程3执行线程1执行线程1执行线程1执行

可见三个线程各自并行执行,并无明确的先后顺序。但如果我们在t.start()后面加上这行代码,

//代码块2t1.start();t1.join();

看会出现看什么样的结果:

线程1执行线程1执行线程1执行线程1执行线程1执行线程2执行线程3执行线程3执行线程2执行线程3执行线程2执行线程3执行线程2执行线程3执行线程2执行

可以看到线程1执行结束之后线程2和3才开始执行,可见在线程1执行过程中,其他线程并未执行,线程1结束后,线程2,线程3开始并行执行,这就印证了前面的结论,即:join的作用是在多线程环境下暂时以单线程执行。明白了这一点,接下来的问题是,这个特性是怎么实现的呢?我们跟到源码:可以看到

//代码块3

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;    }}

}

在第12行调用了wait,注意这里的wait,它并不是指线程线程1对象执行wait,而是线程1的调用者,也就是相当于在主线程去执行wait,可等价理解为以下伪代码:

t1.start();while(t1.isAlive()){    Thread.currentThread().doWait()}

此时执行流程会在代码块3的11-13行循环执行,当线程1执行完毕时,其生命周期结束,isAlive()返回false,11-13行退出循环,继续执行下面的代码,此时又切换为并行执行状态。对于以上执行效果,我们完全可以不用创建t1线程,而是把在主线程中直接去调用t1的核心逻辑,代码如下:

public static void main(String[] args) throws InterruptedException {    //Thread t1 = 
new Thread(new DoSth(), 
"线程1");    Thread t2 = 
new Thread(new DoSth(), 
"线程2");    Thread t3 = 
new Thread(new DoSth(), 
"线程3");    //t1.start();    //t1.join();    new DoSth().run();//直接调用业务逻辑,而不是分配线程去执行    t2.start();    t3.start();    System.out.println("主线程执行");}

和之前的代码相比,本来需要在子线程t1中执行的内容,通过在主线程中执行达到了相同的效果,而这种特性,就体现了所谓的join,现在你明白为什么叫join了吧?join在实际应用当中有什么用呢?把以上代码改造一下,用一个例子来说明。

public static void main(String[] args) throws InterruptedException {    Thread t1 = 
new Thread(new DoSth(), 
"小组1");    Thread t2 = 
new Thread(new DoSth(), 
"小组2");    Thread t3 = 
new Thread(new DoSth(), 
"小组3");    t1.start();    t2.start();    t3.start();    t1.join();    t2.join();    t3.join();    System.out.println("集合完毕");}

执行结果:

小组3正在集合小组1正在集合小组2正在集合小组3正在集合小组1正在集合小组2正在集合小组3正在集合小组1正在集合集合完毕

当我们需要多个子线程分布去完成各自的任务,并在这些子线程全部完成后,主线程做统一汇总时,join就派上用场了。不过细心的读者会发现,这些子线程并未返回任何结果,如果我们需要返回结果供主线程使用时,该怎么实现,针对这一需求,单靠实现Runnable的方式已经无法做到了,此时需要用到另外的接口:Feature和Callable。

以上是“Java中join有什么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:http://blog.itpub.net/69923331/viewspace-2704761/

AI

开发者交流群×