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 系列类。
点击查看 Java 的 FutureTask介绍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值