专栏首页程序那些事java中join的使用

java中join的使用

join()应该是我们在java中经常会用到的一个方法,它主要是将当前线程置为WAITTING状态,然后等待调用的线程执行完毕或被interrupted。

join()是Thread中定义的方法,我们看下他的定义:

   /**
     * Waits for this thread to die.
     *
     * <p> An invocation of this method behaves in exactly the same
     * way as the invocation
     *
     * <blockquote>
     * {@linkplain #join(long) join}{@code (0)}
     * </blockquote>
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final void join() throws InterruptedException {
        join(0);
    }

我们看下join是怎么使用的,通常我们需要在线程A中调用线程B.join():

public class JoinThread implements Runnable{
    public int processingCount = 0;

    JoinThread(int processingCount) {
        this.processingCount = processingCount;
        log.info("Thread Created");
    }

    @Override
    public void run() {
        log.info("Thread " + Thread.currentThread().getName() + " started");
        while (processingCount > 0) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                log.info("Thread " + Thread.currentThread().getName() + " interrupted");
            }
            processingCount--;
        }
        log.info("Thread " + Thread.currentThread().getName() + " exiting");
    }

    @Test
    public void joinTest()
            throws InterruptedException {
        Thread t2 = new Thread(new JoinThread(1));
        t2.start();
        log.info("Invoking join");
        t2.join();
        log.info("Returned from join");
        log.info("t2 status {}",t2.isAlive());
    }
}

我们在主线程中调用了t2.join(),则主线程将会等待t2执行完毕,我们看下输出结果:

06:17:14.775 [main] INFO com.flydean.JoinThread - Thread Created
06:17:14.779 [main] INFO com.flydean.JoinThread - Invoking join
06:17:14.779 [Thread-0] INFO com.flydean.JoinThread - Thread Thread-0 started
06:17:15.783 [Thread-0] INFO com.flydean.JoinThread - Thread Thread-0 exiting
06:17:15.783 [main] INFO com.flydean.JoinThread - Returned from join
06:17:15.783 [main] INFO com.flydean.JoinThread - t2 status false

当线程已经执行完毕或者还没开始执行的时候,join()将会立即返回:

Thread t1 = new SampleThread(0);
t1.join();  //returns immediately

join还有两个带时间参数的方法:

public final void join(long millis) throws InterruptedException
public final void join(long millis,int nanos) throws InterruptedException

如果在给定的时间内调用的线程没有返回,则主线程将会继续执行:

    @Test
    public void testJoinTimeout()
            throws InterruptedException {
        Thread t3 =  new Thread(new JoinThread(10));
        t3.start();
        t3.join(1000);
        log.info("t3 status {}", t3.isAlive());
    }

上面的例子将会输出:

06:30:58.159 [main] INFO com.flydean.JoinThread - Thread Created
06:30:58.163 [Thread-0] INFO com.flydean.JoinThread - Thread Thread-0 started
06:30:59.172 [main] INFO com.flydean.JoinThread - t3 status true

Join()还有个happen-before的特性,这就是如果thread t1调用 t2.join(), 那么当t2返回时,所有t2的变动都会t1可见。

之前我们讲volatile关键词的时候也提到了这个happen-before规则。我们看下例子:

    @Test
    public void testHappenBefore() throws InterruptedException {
        JoinThread t4 =  new JoinThread(10);
        t4.start();
        // not guaranteed to stop even if t4 finishes.
        do {
            log.info("inside the loop");
            Thread.sleep(1000);
        } while ( t4.processingCount > 0);
    }

我们运行下,可以看到while循环一直在进行中,即使t4中的变量已经变成了0。

所以如果我们需要在这种情况下使用的话,我们需要用到join(),或者其他的同步机制。

本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/join

本文分享自微信公众号 - 程序那些事(flydean-tech),作者:flydean

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java中IO和NIO的本质和区别

    终于要写到java中最最让人激动的部分了IO和NIO。IO的全称是input output,是java程序跟外部世界交流的桥梁,IO指的是java.io包中的所...

    程序那些事
  • java安全编码指南之:Thread API调用规则

    java中多线程的开发中少不了使用Thread,我们在使用Thread中提供的API过程中,应该注意些什么规则呢?

    程序那些事
  • 新版gitbook导出pdf

    最近想把自己写的一个gitbook转成pdf分享出去,突然发现最新的gitbook版本已经不支持导出PDF了。于是在网上找了好久终于被我发现了三个将gitboo...

    程序那些事
  • 【SQL 基础】游标(curosr)

    也许大家对数据库中游标都不陌生,但对于其概念可能有时又会有些模糊,游标到底是什么? 为了使大家对游标有个清晰的认识,本文将介绍Oracle中游标(curosr)...

    TeacherWhat
  • 2014移动互联网数据报告(91PPT)

    大数据文摘
  • python的Gzip模块

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    于小勇
  • 07-08 创建计算字段使用函数处理数据第7章 创建计算字段第8章 使用函数处理数据

    上述例子中,存储在表中的数据都不是应用程序所需要的。我们需要直接从数据库中检索出转换、计算或格式化过的数据,而不是检索出数据,然后再在客户端应用程序中重新格式化...

    用户1250179
  • 收藏 | 知识图谱论文大合集,干货满满的笔记解读(附资源)

    远程监督关系抽取方法虽然可以使用知识库对齐文本的方法得到大量标注数据,但是其中噪声太多,影响模型的训练效果。基于 bag 建模比基于句子建模能够减少噪声的影响,...

    数据派THU
  • 【PMP】8.23下午题

    1、项目办公室刚刚发布给你一份项目状况检查报告,当你看到在执行总结中标题为“建议”的章节时,你的心情激动起来,你又一次被批评没有为项目提供足够的支持细节。尽管报...

    心跳包
  • 手把手教你如何面试,你要的我都有(简历篇)

    连续好几周,在一些渠道看到关于年底优化的故事,很多小伙伴要么自己中招,要么眼睁睁看着身边同事中招,充满焦虑。亦或者有些小伙伴本身就有被优化的打算,也趁此抓住机会...

    程序员小跃

扫码关注云+社区

领取腾讯云代金券