CompletableFuture源码分析

接口设计

public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {

CompletableFuture实现了Future接口和CompletionStage接口。

Future接口可以方便的获取多线程异步执行时的结果,当线程异步执行结束之后,返回的结果将会保存在Future中。

CompletionStage接口代表了一个异步执行的动作阶段,当执行完一个动作阶段后会返回新的CompletionStage,通过CompletionStage可以关联成链式结构。

CompletionStage接口

一个阶段的执行计算可以通过调用Function接口, Consumer接口 或 Runnable接口去实现。其中包含有同步执行,异步执行(Async)和指定异步执行的线程池(Executor)。

Function接口:

public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);
public <U> CompletionStage<U> applyToEither(CompletionStage<? extends T> other,Function<? super T, U> fn);
 ...

Consumer接口:

public CompletionStage<Void> thenAccept(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor);
public CompletionStage<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action);
...

Runnable接口:

public CompletionStage<Void> thenRun(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable action,Executor executor);
public CompletionStage<Void> runAfterEither(CompletionStage<?> other,Runnable action);
 ... 

一个阶段的执行可以在上一个阶段,或者多个阶段,或者多个阶段中的任何一个阶段执行完成后执行

结构设计

volatile Object result;       // Either the result or boxed AltResult
volatile Completion stack;    // Top of Treiber stack of dependent actions

CompletableFuture 由 result(当前计算结果),stack(Completion通过链表实现栈来记录当前计算完成后需要触发的依赖动作)组成

CompletableFuture<String> completableFuture =
            CompletableFuture.supplyAsync(() -> "stage one").thenApplyAsync(s -> s + " stage two");

上面示例中第二个任务的执行依赖第一个任务的执行结果,我们通过分析supplyAsync 和thenApplyAsync方法来理解CompletableFuture的运行实现原理

supplyAsync

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

asyncPool为ForkJoinPool.commonPool()默认线程池,supplier为需要执行的任务逻辑

static <U> CompletableFuture<U> asyncSupplyStage(Executor e,Supplier<U> f) {
        if (f == null) throw new NullPointerException();
        CompletableFuture<U> d = new CompletableFuture<U>();
        e.execute(new AsyncSupply<U>(d, f));
        return d;
    }

Executor e不指定线程池时为ForkJoinPool.commonPool()默认线程池,若通过supplyAsync(Supplier<U> supplier,Executor executor)指定特定线程池时为我们此时传入的线程池,此时在执行任务前通过包装为AsyncSupply来执行任务

复制代码
static final class AsyncSupply<T> extends ForkJoinTask<Void>
            implements Runnable, AsynchronousCompletionTask {
        CompletableFuture<T> dep; Supplier<T> fn;
        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 {
                        d.completeValue(f.get());
                    } catch (Throwable ex) {
                        d.completeThrowable(ex);
                    }
                }
                d.postComplete();
            }
        }
    }
复制代码

AsyncSupply继承了ForkJoinTask,实现了Runnable保证既可以执行默认ForkJoinPool.commonPool()又可以执行自定义的线程池。f.get()开始执行任务逻辑,completeValue方法将执行的结果通过CAS方式设置到result中,之后通过postComplete执行后续动作

复制代码
final void postComplete() {
        /*
         * On each step, variable f holds current dependents to pop
         * and run.  It is extended along only one path at a time,
         * pushing others to avoid unbounded recursion.
         */
        CompletableFuture<?> f = this; Completion h;
        while ((h = f.stack) != null ||
               (f != this && (h = (f = this).stack) != null)) {
            CompletableFuture<?> d; Completion t;
            if (f.casStack(h, t = h.next)) {
                if (t != null) {
                    if (f != this) {
                        pushStack(h);
                        continue;
                    }
                    h.next = null;    // detach
                }
                f = (d = h.tryFire(NESTED)) == null ? this : d;
            }
        }
    }
复制代码

postComplete中若stack栈顶元素不为空,取到stack栈顶元素,f.casStack(h, t = h.next)通过CAS将栈顶指针后移,执行栈中的每个Completion的tryFire方法,若Completion的tryFire方法返回了另外的CompletableFuture,并且另外的CompletableFuture中的stack不为空,会逐个将stack中的Completion压入原CompletableFuture的栈中。当原CompletableFuture对象Completion栈中所有引用的CompletableFuture中的Completion都压入原CompletableFuture栈后,原CompletableFuture就会依次执行栈中Completion的tryFire方法

复制代码
abstract static class Completion extends ForkJoinTask<Void>
        implements Runnable, AsynchronousCompletionTask {
        volatile Completion next;      // Treiber stack link

        /**
         * Performs completion action if triggered, returning a
         * dependent that may need propagation, if one exists.
         *
         * @param mode SYNC, ASYNC, or NESTED
         */
        abstract CompletableFuture<?> tryFire(int mode);

        /** Returns true if possibly still triggerable. Used by cleanStack. */
        abstract boolean isLive();

        public final void run()                { tryFire(ASYNC); }
        public final boolean exec()            { tryFire(ASYNC); return true; }
        public final Void getRawResult()       { return null; }
        public final void setRawResult(Void v) {}
    }
复制代码

Completion中tryFire为定义的模板抽象方法,可以通过三种模式执行:SYNC(同步模式),ASYNC(异步模式),NESTED(嵌套模式)

thenApplyAsync

public <U> CompletableFuture<U> thenApplyAsync(
        Function<? super T,? extends U> fn) {
        return uniApplyStage(asyncPool, fn);
    }
复制代码
private <V> CompletableFuture<V> uniApplyStage(
        Executor e, Function<? super T,? extends V> f) {
        if (f == null) throw new NullPointerException();
        CompletableFuture<V> d =  new CompletableFuture<V>();
        if (e != null || !d.uniApply(this, f, null)) {
            UniApply<T,V> c = new UniApply<T,V>(e, d, this, f);
            push(c);
            c.tryFire(SYNC);
        }
        return d;
    
复制代码

同步执行时Executor e为null,异步执行会传入线程池。thenApplyAsync在异步执行时为ForkJoinPool.commonPool()线程池,之后尝试将包装的UniApply压入原CompletableFuture栈中,此时原CompletableFuture有可能任务已经执行完成(此时压栈失败),所以需要执行UniApply类实现的tryFire方法

final CompletableFuture<V> tryFire(int mode) {
            CompletableFuture<V> d; CompletableFuture<T> a;
            if ((d = dep) == null ||
                !d.uniApply(a = src, fn, mode > 0 ? null : this))
                return null;
            dep = null; src = null; fn = null;
            return d.postFire(a, mode);
}

tryFire方法中执行uniApply方法,uniApply中当前CompletableFuture任务若执行完成,返回true,执行下面的postFire方法

复制代码
final <S> boolean uniApply(CompletableFuture<S> a,
                               Function<? super S,? extends T> f,
                               UniApply<S,T> c) {
        Object r; Throwable x;
        if (a == null || (r = a.result) == null || f == null)
            return false;
        tryComplete: if (result == null) {
            if (r instanceof AltResult) {
                if ((x = ((AltResult)r).ex) != null) {
                    completeThrowable(x, r);
                    break tryComplete;
                }
                r = null;
            }
            try {
                if (c != null && !c.claim())
                    return false;
                @SuppressWarnings("unchecked") S s = (S) r;
                completeValue(f.apply(s));
            } catch (Throwable ex) {
                completeThrowable(ex);
            }
        }
        return true;
    }
复制代码

CompletableFuture<S> a为原CompletableFuture,若原CompletableFuture的任务已经执行完成,当前CompletableFuture的任务还未完成, 在原CompletableFuture执行成功的情况下执行当前CompletableFuture的任务,执行成功后返回ture

复制代码
final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
        if (a != null && a.stack != null) {
            if (mode < 0 || a.result == null)
                a.cleanStack();
            else
                a.postComplete();
        }
        if (result != null && stack != null) {
            if (mode < 0)
                return this;
            else
                postComplete();
        }
        return null;
    }
复制代码

postFire方法中a为原CompletableFuture,mode为具体模式 SYNC(同步模式:0),ASYNC(异步模式:1),NESTED(嵌套模式:-1)。若为嵌套执行模式(mode<0),或原CompletableFuture任务未执行完成(a.result == null),执行cleanStack方法(将栈中无效的Completion清除掉),其它情况执行postComplete方法。若当前CompletableFuture任务已经执行完成(result != null),并且栈中有要执行的Completion(stack != null),且为嵌套模式时(mode < 0),返回该对象本身(后续由外部postComplete执行),其它模式直接执行postComplete。

posted @   sunnycony  阅读(94)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示