Java并发编程 — join()

join() 等待线程结束, 当我们调用某个线程的这个方法时,这个方法会挂起调用线程,直到被调用线程结束执行,调用线程才会继续执行

join() 描述

Java 7 Concurrency Cookbook 中相关的描述

原文:

Waiting for the finalization of a thread

In some situations, we will have to wait for the finalization of a thread. For example, we may have a program that will begin initializing the resources it needs before proceeding with the rest of the execution. We can run the initialization tasks as threads and wait for its finalization before continuing with the rest of the program. For this purpose, we can use the join() method of the Thread class. When we call this method using a thread object, it suspends the execution of the calling thread until the object called finishes its execution.

译文:

等待线程完成

在某些情况下,我们将不得不等待线程的终结。例如,我们可能有一个程序,在继续执行其余的部分之前,它将开始初始化所需的资源。我们可以将初始化任务作为线程运行,并等待其完成,然后再继续执行其余的程序。为此,我们可以使用线程类的join()方法。当我们使用线程对象调用此方法时,它将挂起调用线程的执行,直到被调用的对象完成其执行。

join() 代码示例

public class CommonCook {

    public static void main(String[] args) throws InterruptedException {
        long startTime = System.currentTimeMillis();
        // 第一步 网购厨具
        OnlineShopping thread = new OnlineShopping();
        thread.start();
        thread.join();  // 保证厨具送到
        // 第二步 去超市购买食材
        Thread.sleep(2000);  // 模拟购买食材时间
        Shicai shicai = new Shicai();
        System.out.println("第二步:食材到位");
        // 第三步 用厨具烹饪食材
        System.out.println("第三步:开始展现厨艺");
        cook(thread.chuju, shicai);
        System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");
    }
    // 网购厨具线程
    static class OnlineShopping extends Thread {
        private Chuju chuju;
        @Override
        public void run() {
            System.out.println("第一步:下单");
            System.out.println("第一步:等待送货");
            try {
                Thread.sleep(5000);  // 模拟送货时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("第一步:快递送到");
            chuju = new Chuju();
        }
        
    }

    //  用厨具烹饪食材
    static void cook(Chuju chuju, Shicai shicai) {}
    
    // 厨具类
    static class Chuju {}
    
    // 食材类
    static class Shicai {}
} 

运行结果

第一步:下单
第一步:等待送货
第一步:快递送到
第二步:食材到位
第三步:开始展现厨艺
总共用时7009ms

但 如果把 join() 方法放到 cook() 前,通过时间和执行顺序很容易理解两者差异和 join() 的作用

1554257099(1).jpg

通过 new() 新建子线程 (此时处于NEW状态),再调用start()(转换为 RUNNABLE 状态)
调用 join() 后 子线程 正常运行,父线程进入等待,子线程结束后父线程继续运行


文章参考 北斗玄机

发表留言

人生在世,错别字在所难免,无需纠正。

icon_mrgreen.gificon_neutral.gificon_twisted.gificon_arrow.gificon_eek.gificon_smile.gificon_confused.gificon_cool.gificon_evil.gificon_biggrin.gificon_idea.gificon_redface.gificon_razz.gificon_rolleyes.gificon_wink.gificon_cry.gificon_surprised.gificon_lol.gificon_mad.gificon_sad.gificon_exclaim.gificon_question.gif