Java8 CompletableFuture(一) 源码解析

本文详细探讨了Java8 CompletableFuture的实现细节,包括它的定义、supplyAsync/runAsync方法、完成方法、thenApply系列方法、UniApply等内部类的实现、回调触发逻辑以及get/join/cancel等相关方法的工作原理。
摘要由CSDN通过智能技术生成

目录

1、定义

2、supplyAsync / runAsync

3、completeNull / completeValue / completeThrowable / completeRelay 

4、thenApply / thenAccept / thenRun

5、UniApply / UniAccept / UniRun

6、postComplete / postFire

7、触发逻辑测试用例

8、get / join / getNow / cancel

9、Signaller


上一篇《Java8 CompletableFuture 用法全解》探讨了CompletableFuture的用法,本篇博客就详细探讨该类的实现细节。

1、定义

     CompletableFuture的类继承关系如下:

CompletionStage是Java8引入的支持异步回调和多个任务组合处理的Future接口的增强版,上篇博客中介绍的thenApply,thenApply等方法都是该接口定义的,CompletableFuture是该接口的唯一实现类。该类包含的属性如下:

 //任务的执行结果或者异常信息
 volatile Object result;       // Either the result or boxed AltResult
 
 //待触发的回调方法,如果同一个异步任务有多个回调方法,则多个回调方法通过next属性构成一个链表,
//最后一个添加的回调方法就是stack属性的值,即最后一个添加的回调方法会被最先触发
 volatile Completion stack;    // Top of Treiber stack of dependent actions

 static final AltResult NIL = new AltResult(null);

 //是否使用common线程池,如果是多核处理器则是true
 private static final boolean useCommonPool =
        (ForkJoinPool.getCommonPoolParallelism() > 1);

 //默认的Executor实现
 private static final Executor asyncPool = useCommonPool ?
        ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();

 //tryFire的三种模式,
 //SYNC表示同步调用,添加回调任务时会尝试执行回调任务,此时的触发模式就是SYNC
 static final int SYNC   =  0;
 
 //ASYNC表示异步调用,通过指定线程池完成某个回调方法时,触发的模式就是ASYNC
 static final int ASYNC  =  1;
 
 //NESTED表示内部调用,通过postComplete方法触发
 static final int NESTED = -1;

  其中Completion是一个继承自ForkJoinTask的抽象内部类,其定义如下:

通过next属性多个Completion便构成了链表关系。Completion有多个子类,这些子类就是CompletionStage接口实现的核心,如下图:

后面会相信介绍相关子类的实现。AltResult和ThreadPerTaskExecutor都是内部类,其定义如下:

除上述属性外,还有多个表示字段偏移量的属性,通过static代码块初始化,如下:

该类对外的构造方法只有默认的无参构造方法,不设置任何属性,如下:

2、supplyAsync / runAsync

      这两个方法都是用来创建异步任务并提交到线程池中,可通过返回的CompletableFuture实例获取任务执行的状态和结果,区别在于supplyAsync有返回值而runAsync无返回值。

public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        return asyncSupplyStage(asyncPool, supplier);
    }

public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
                                                       Executor executor) {
        return asyncSupplyStage(screenExecutor(executor), supplier);
    }

public static CompletableFuture<Void> runAsync(Runnable runnable) {
        return asyncRunStage(asyncPool, runnable);
    }

public static CompletableFuture<Void> runAsync(Runnable runnable,
                                                   Executor executor) {
        return asyncRunStage(screenExecutor(executor), runnable);
    }

static <U> CompletableFuture<U> asyncSupplyStage(Executor e,
                                                     Supplier<U> f) {
        if (f == null) throw new NullPointerException();
        CompletableFuture<U> d = new CompletableFuture<U>();
        //提交异步任务,会调用AsyncSupply的run方法
        e.execute(new AsyncSupply<U>(d, f));
        //可以根据实例d获取f的执行状态和结果
        return d;
    }

static Executor screenExecutor(Executor e) {
        if (!useCommonPool && e == ForkJoinPool.commonPool())
            return asyncPool; //如果useCommonPool为false,则不能使用common线程池
        if (e == null) throw new NullPointerException();
        return e;
    }

static CompletableFuture<Void> asyncRunStage(Executor e, Runnable f) {
        if (f == null) throw new NullPointerException();
        CompletableFuture<Void> d = new CompletableFuture<Void>();
        //提交异步任务
        e.execute(new AsyncRun(d, f));
        return d;
    }

  其中AsyncSupply和AsyncRun都是两个继承自ForkJoinTask的内部类,其实现如下:

static final class AsyncSupply<T> extends ForkJoinTask<Void>
            implements Runnable, AsynchronousCompletionTask {
        CompletableFuture<T> dep; Supplier<T> fn;

        //注意dep会被返回,用于获取fn的执行状态和执行结果,而不是AsyncSupply本身
        AsyncSupply(CompletableFuture<T> dep, Supplier<T> fn) {
            this.dep = dep; this.fn = fn;
        }

        public final Void getRawResult() { return null; }
        public final void setRawResult(Void v) {}
        public final boolean exec() { run(); return true; }

        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 {
                        //执行f.get就是执行异步任务,并通过completeValue保存结果
                        d.completeValue(f.get());
                    } catch (Throwable ex) {
                        //执行异常,保存异常信息
                        d.completeThrowable(ex);
                    }
                }
                //做事后处理
                d.postComplete();
            }
        }
    }

static final class AsyncRun extends ForkJoinTask<Void>
            implements Runnable, AsynchronousCompletionTask {
        CompletableFuture<Void> dep; Runnable fn;

        //同上dep会被返回
        AsyncRun(CompletableFuture<Void> dep, Runnable fn) {
            this.dep = dep; this.fn = fn;
        }

        public final Void getRawResult() { return null; }
        public final void setRawResult(Void v) {}
        public final boolean exec() { run(); return true; }

        public void run() {
            CompletableFuture<Void> d; Runnable f;
            if ((d = dep) != null && (f = fn) != null) {
                dep = null; fn = null;
                if (d.result == null) {
                    try {
                        f.run();
                        //执行完成,设置返回值为null
                        d.completeNull();
                    } catch (Throwable ex) {
                        //执行异常,保存异常信息
                        d.completeThrowable(ex);
                    }
                }
                //做事后处理
                d.postComplete();
            }
        }
    }

3、completeNull / completeValue / completeThrowable / completeRelay 

      这几个方法都是CAS修改result属性,保存任务执行的结果或者执行异常时抛出的异常信息。

final boolean completeNull() {
        //cas修改result属性
        return UNSAFE.compareAndSwapObject(this, RESULT, null,
                                           NIL);
    }

final boolean completeValue(T t) {
        return UNSAFE.compareAndSwapObject(this, RESULT, null,
                                           (t == null) ? NIL : t);
    }

final boolean completeThrowable(Throwable x) {
        return UNSAFE.compareAndSwapObject(this, RESULT, null,
                                           encodeThrowable(x));
    }

final boolean completeThrowable(Throwable x, Object r) {
        return UNSAFE.compareAndSwapObject(this, RESULT, null,
                                           encodeThrowable(x, r));
    }

final boolean completeRelay(Object r) {
        return UNSAFE.compareAndSwapObject(this, RESULT, null,
                                           encodeRelay(r));
    }


//将x用CompletionException包装一层
static AltResult encodeThrowable(Throwable x) {
        return new AltResult((x instanceof CompletionException) ? x :
                             new CompletionException(x));
    }

//使用CompletionException 或者 AltResult包装一层
static Object encodeThrowable(Throwable x, Ob
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值