JDK源码之CompletableFuture(一)结果返回原理

JDK源码之CompletableFuture(一)结果返回原理
JDK源码之CompletableFuture(二)链式调用原理
JDK源码之CompletableFuture(三)anyOf,allOf是怎么实现的?


在jdk8中有一个并发类,叫做CompletableFuture,它的出现可以说功能上基本可以取代CountDownLatch,CyclicBarrier,信号量等等的功能,并且可以做到链式调用,非常的好用,可以 说会了这个CompletableFuture,并掌握其原理,你基本可以应付你工作中所有的并发问题

一、CompletableFuture抬手第一步

CompletableFuture有两个方法创建,分别是:

        CompletableFuture.runAsync();
        CompletableFuture.supplyAsync();

区别就是一个有返回结果,一个没有返回结果。

  • 线程池参数:可以不传,不传就用默认的ForkJoinPool
    注意: 尽量用自己创建的线程池,因为ForkJoinPool中创建的线程池默认是后台线程,图示如下:
    后台线程
    在主线程退出时,后台线程也就结束了,会发生预想不到的问题。可以在主线程中用future的get()方法获取结果来阻塞,但是作为一位好的程序员,结合业务自定义线程池是必备的技能点。

二、CompletableFuture是如何获取返回结果的?

在线程池执行的时候,使用了这么一个类AsyncSupply

e.execute(new AsyncSupply<U>(d, f));

这个类定义如下:

    static final class AsyncSupply<T> extends ForkJoinTask<Void>
            implements Runnable, AsynchronousCompletionTask {

既然能被线程池执行,我们直接看其run方法:


        public void run() {
            CompletableFuture<T> d; Supplier<T> f;
            if ((d = dep) != null && (f = fn) != null) {
                dep = null; fn = null;
                if (d.result == null) {
                    try {
                        d.completeValue(f.get());
                    } catch (Throwable ex) {
                        d.completeThrowable(ex);
                    }
                }
                d.postComplete();
            }
        }
  • 可以看到获取到结果后,会有一个completeValue方法,将结果设置到result参数上
  • 而Future.get()就是在轮询result的值,直到result的值不为空就获取到结果了。

三、总结

这次我们从源码角度说了

  • CompletableFuture创建使用线程池和不使用线程池的方式
  • CompletableFuture返回结果的原理

后面一篇文章,我们开始聊聊CompletableFuture是如何实现链式调用的

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值