join 异步阻塞介绍

简介: 阻塞当前的线程,直到准备合并的目标线程的执行完成。

join 异步阻塞介绍

join 操作的原理是:

阻塞当前的线程,直到准备合并的目标线程的执行完成。

线程的 join 合并流程:

在 Java 中,线程(Thread)的合并流程是:假设线程 A 调用了线程 B 的 B.join 方法,合并 B线程。那么,线程 A 进入阻塞状态,直到 B 线程执行完成。

使用 join 实现异步泡茶喝的实践案例

流程图:
join 实现异步泡茶喝的流程
代码实现:

public class JoinDemo {
    public static final int SLEEP_GAP = 500;

    public static String getCurThreadName() {
        return Thread.currentThread().getName();
    }

    static class HotWaterThread extends Thread {
        public HotWaterThread() {
            super("** 烧水—Thread");
        }

        @Override
        public void run() {
            try {
                System.out.println("洗好水壶");
                System.out.println("灌上凉水");
                System.out.println("放在火上");
                //睡一段时间 代表烧水
                Thread.sleep(SLEEP_GAP);
                System.out.println("水烧好了。");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("烧水 线程结束");
        }
    }

    static class WashThread extends Thread {
        public WashThread() {
            super("$$ 清洗线程");
        }

        @Override
        public void run() {

            try {
                System.out.println("洗茶杯");
                System.out.println("洗水壶");
                //睡一段时间 洗水壶
                Thread.sleep(SLEEP_GAP);
                System.out.println("洗完了。");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("清洗 线程结束");
        }
    }


    public static void main(String[] args) {
        HotWaterThread hotWaterThread = new HotWaterThread();
        WashThread washThread = new WashThread();
        hotWaterThread.start();
        washThread.start();
        try {
            //合并烧水线程
            hotWaterThread.join();
            //合并清洗线程
            washThread.join();
            Thread.currentThread().setName("主线程");
            System.out.println("泡喝茶~~~");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("真好喝 拜拜~ 运行结束!");
    }
}

程序中有三个线程:(1)主线程 main;(2)烧水线程 hThread;(3)清洗线程 wThread。
main 主线程调用了 hThread.join()实例方法,合并烧水线程,也调用了 wThread.join()实例方法,合并清洗线程。

join 合并方法:

join 方法的应用场景:A 线程调用 B 线程的 join 方法,等待 B 线程执行完成;在 B 线程没有完成前,A 线程阻塞。

join 方法是有三个重载版本:

(1)void join():A 线程等待 B 线程执行结束后,A 线程重新恢复执行。
(2)void join(long millis):A 线程等待 B 线程执行一段时间,最长等待时间为 millis 毫秒。 超过 millis 毫秒后,不论 B 线程是否结束,A 线程重新恢复执行。
(3)void join(long millis,int nanos):等待 B 线程执行一段时间,最长等待时间为 millis 毫秒, 加 nanos 纳秒。超过时间后,不论 B 线程是否结束,A 线程重新恢复执行。

注意以下容易混淆的几点:

(1)join 是实例方法,不是静态方法,需要使用线程对象去调用,如 thread.join()。
(2)join 调用时,不是线程所指向的目标线程阻塞,而是当前线程阻塞。
(3)只有等到当前线程所指向的线程执行完成,或者超时,当前线程才能重新恢复执行。

join 有一个问题:被合并的线程没有返回值。例如,在烧水的实例中,如果烧水线程的执行结束,main 线程是无法知道结果的。同样,清洗线程的执行结果,main 线程也是无法知道的。形象地说,join 线程合并就是一像一个闷葫芦。只能发起合并线程,不能取到执行结果。

如果需要获得异步线程的执行结果,怎么办呢?可以使用 Java 的 FutureTask 系列类。

目录
相关文章
阻塞式/非阻塞式与同步/异步的区别
阻塞式/非阻塞式与同步/异步的区别
95 0
理解阻塞、非阻塞与同步、异步的区别
理解阻塞、非阻塞与同步、异步的区别
理解阻塞、非阻塞与同步、异步的区别
|
调度 C++
进程、线程、并发、并行、同步、异步、阻塞、非阻塞
乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。
阻塞/阻塞/同步/异步
咱就说有没有一种可能,同步、异步、阻塞、非阻塞,这几个关键词拆开看都感觉挺明白的。但是同步阻塞、同步非阻塞、异步阻塞、异步非阻塞,这几个关键词组装起来,看起来就有点那么晦涩了。这个在日常八股中经常出现字眼,其背后对应的到底是个什么样的逻辑?我们来一起揭开它那不那么神秘的面纱。/手动狗头。
120 0
阻塞/阻塞/同步/异步
|
缓存 Java
同步 异步 阻塞 非阻塞
在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解。具体如下:  序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步非阻塞? 7 什么是异步阻塞? 8 什么是异步非阻塞? 散仙不才,在查了一部分资料后,愿试着以通俗易懂的方式
1885 1
同步、异步、阻塞、非阻塞
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication) 真正意义上的 异步IO 是说内核直接将数据拷贝至用户态的内存单元,再通知程序直接去读取数据。
1005 0
同步,异步,阻塞和非阻塞
同步,异步,阻塞和非阻塞的理解
1663 0