【JUC源码解析】CompletableFuture
简介
先说Future, 它用来描述一个异步计算的结果。isDone方法可以用来检查计算是否完成,get方法可以用来获取结果,直到完成前一直阻塞当前线程,cancel方法可以取消任务。而对于结果的获取,只能通过阻塞(get())或者轮询的方式[while(!isDone)]. 阻塞的方式违背了异步编程的理念,轮询的方式耗费无谓的CPU资源(CPU空转)。于是,CompletableFuture应运而生。
样例
后面介绍的源码都会以下面的用例为切入点,循着调用轨迹理解源码。如果任务很耗时,记得传Executor, 或者方法末尾加上future.get(); 因为CompletableFuture默认使用ForkJoinPool, 而ForkJoinPool里面的线程都是daemon线程,主线程跑完了,虚拟机也就over了。
- public void whenComplete() {
- CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
- future.whenComplete((l, r) -> System.out.println(l));
- }
- public void thenApply() {
- CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
- future.thenApply(i -> -i);
- }
- public void thenAccept() {
- CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
- future.thenAccept(System.out::println);
- }
- public void thenRun() {
- CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
- future.thenRun(() -> System.out.println("Done"));
- }
- public void thenAcceptBoth() {
- CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
- CompletableFuture<Integer> other = CompletableFuture.supplyAsync(() -> 200);
- future.thenAcceptBoth(other, (x, y) -> System.out.println(x + y));
- }
- public void acceptEither() {
- CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
- CompletableFuture<Integer> other = CompletableFuture.supplyAsync(() -> 200);
- future.acceptEither(other, System.out::println);
- }
- public void allOf() {
- CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
- CompletableFuture<Integer> second = CompletableFuture.supplyAsync(() -> 200);
- CompletableFuture<Integer> third = CompletableFuture.supplyAsync(() -> 300);
- CompletableFuture.allOf(future, second, third);
- }
- public void anyOf() throws InterruptedException, ExecutionException {
- CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 100);
- CompletableFuture<Integer> second = CompletableFuture.supplyAsync(() -> 200);
- CompletableFuture<Integer> third = CompletableFuture.supplyAsync(() -> 300);
- CompletableFuture.anyOf(future, second, third);
- }
源码分析
supplyAsync
supplyAsync(Supplier<U> supplier)
- public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
- return asyncSupplyStage(asyncPool, supplier); // asyncPool, ForkJoinPool.commonPool()或者ThreadPerTaskExecutor(实现了Executor接口,里面的内容是{new Thread(r).start();})
- }
asyncSupplyStage(Executor e, Supplier<U> f)
- static <U> CompletableFuture<U> asyncSupplyStage(Executor e, Supplier<U> f) {
- if (f == null)
- throw new NullPointerException();
- CompletableFuture<U> d = new CompletableFuture<U>(); // 构建一个新的CompletableFuture, 以此构建AsyncSupply作为Executor的执行参数
- e.execute(new AsyncSupply<U>(d, f)); // AsyncSupply继承了ForkJoinTask, 实现了Runnable, AsynchronousCompletionTask接口
- return d; // 返回d,立返
- }
AsyncSupply
- // CompletableFuture的静态内部类,作为一个ForkJoinTask
- static final class AsyncSupply<T> extends ForkJoinTask<Void> implements Runnable, AsynchronousCompletionTask {
- CompletableFuture<T> dep; // AsyncSupply作为一个依赖Task,dep作为这个Task的Future
- Supplier<T> fn; // fn作为这个Task的具体执行逻辑,函数式编程
- 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) { // 查看任务是否结束,如果已经结束(result != null),直接调用postComplete()方法
- try {
- d.completeValue(f.get()); // 等待任务结束,并设置结果
- } catch (Throwable ex) {
- d.completeThrowable(ex); // 异常
- }
- }
- d.postComplete(); // 任务结束后,会执行所有依赖此任务的其他任务,这些任务以一个无锁并发栈的形式存在
- }
- }
- }
postComplete()
- final void postComplete() {
- CompletableFuture<?> f = this; // 当前CompletableFuture
- Completion h; // 无锁并发栈,(Completion next), 保存的是依靠当前的CompletableFuture一串任务,完成即触发(回调)
- while ((h = f.stack) != null || (f != this && (h = (f = this).stack) != null)) { // 当f的stack为空时,使f重新指向当前的CompletableFuture,继续后面的结点
- CompletableFuture<?> d;
- Completion t;
- if (f.casStack(h, t = h.next)) { // 从头遍历stack,并更新头元素
- if (t != null) {
- if (f != this) { // 如果f不是当前CompletableFuture,则将它的头结点压入到当前CompletableFuture的stack中,使树形结构变成链表结构,避免递归层次过深
- pushStack(h);
- continue; // 继续下一个结点,批量压入到当前栈中
- }
- h.next = null; // 如果是当前CompletableFuture, 解除头节点与栈的联系
- }
- f = (d = h.tryFire(NESTED)) == null ? this : d; // 调用头节点的tryFire()方法,该方法可看作Completion的钩子方法,执行完逻辑后,会向后传播的
- }
- }
- }
示意图
每个CompletableFuture持有一个Completion栈stack, 每个Completion持有一个CompletableFuture -> dep, 如此递归循环下去,是层次很深的树形结构,所以想办法将其变成链表结构。
首先取出头结点,下图中灰色Completion结点,它会返回一个CompletableFuture, 同样也拥有一个stack,策略是遍历这个CompletableFuture的stack的每个结点,依次压入到当前CompletableFuture的stack中,关系如下箭头所示,灰色结点指的是处理过的结点。
第一个Completion结点返回的CompletableFuture, 将拥有的stack里面的所有结点都压入了当前CompletableFuture的stack里面
后续的Completion结点返回的CompletableFuture, 将拥有的stack里面的所有结点都压入了当前CompletableFuture的stack里面,重新构成了一个链表结构,后续也按照前面的逻辑操作,如此反复,便会遍历完所有的CompletableFuture, 这些CompletableFuture(叶子结点)的stack为空,也是结束条件。
postComplete()最后调用的是Completion#tryFire()方法,先看下Completion的数据结构
Completion
- abstract static class Completion extends ForkJoinTask<Void> implements Runnable, AsynchronousCompletionTask {
- volatile Completion next; // 无锁并发栈
- /**
- * 钩子方法,有三种模式,postComplete()方法里面使用的是NESTED模式,避免过深的递归调用 SYNC, ASYNC, or NESTED
- */
- abstract CompletableFuture<?> tryFire(int mode); // run()和exec()都调用了这个钩子方法
- /** 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) {
- }
- }
static final int SYNC = 0; 同步
static final int ASYNC = 1; 异步
static final int NESTED = -1; 嵌套
继承了ForkJoinTask, 实现了Runnable, AsynchronousCompletionTask接口,它有诸多子类,如下图
后面的方法都对应着不同的子类。
先看一个子类UniCompletion
- abstract static class UniCompletion<T,V> extends Completion {
- Executor executor; // 执行器
- CompletableFuture<V> dep; // 依赖的任务
- CompletableFuture<T> src; // 被依赖的任务
- UniCompletion(Executor executor, CompletableFuture<V> dep,
- CompletableFuture<T> src) {
- this.executor = executor; this.dep = dep; this.src = src;
- }
- final boolean claim() { // 如果当前任务可以被执行,返回true,否则,返回false; 保证任务只被执行一次
- Executor e = executor;
- if (compareAndSetForkJoinTaskTag((short)0, (short)1)) {
- if (e == null)
- return true;
- executor = null; // 设置为不可用
- e.execute(this);
- }
- return false;
- }
- final boolean isLive() { return dep != null; }
- }
claim()方法保证任务只被执行一次。
whenComplete
whenComplete()/whenCompleteAsync()
- public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action) {
- return uniWhenCompleteStage(null, action);
- }
- public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action) {
- return uniWhenCompleteStage(asyncPool, action);
- }
xxx和xxxAsync方法的区别是,有没有asyncPool作为入参,有的话,任务直接入参,不检查任务是否完成。uniWhenCompleteStage方法有说明。
uniWhenCompleteStage(Executor e, BiConsumer<? super T, ? super Throwable> f)
- private CompletableFuture<T> uniWhenCompleteStage(Executor e, BiConsumer<? super T, ? super Throwable> f) {
- if (f == null)
- throw new NullPointerException();
- CompletableFuture<T> d = new CompletableFuture<T>(); // 构建future
- if (e != null || !d.uniWhenComplete(this, f, null)) { // 如果线程池不为空,直接构建任务入栈,并调用tryFire()方法;否则,调用uniWhenComplete()方法,检查依赖的那个任务是否完成,没有完成返回false,
- // 完成了返回true, 以及后续一些操作。
- UniWhenComplete<T> c = new UniWhenComplete<T>(e, d, this, f); // UniWhenComplete继承了UniCompletion
- push(c);
- c.tryFire(SYNC); // 先调一下钩子方法,检查一下任务是否结束
- }
- return d;
- }
uniWhenComplete(CompletableFuture<T> a, BiConsumer<? super T, ? super Throwable> f, UniWhenComplete<T> c)
- final boolean uniWhenComplete(CompletableFuture<T> a, BiConsumer<? super T, ? super Throwable> f, UniWhenComplete<T> c) {
- Object r;
- T t;
- Throwable x = null;
- if (a == null || (r = a.result) == null || f == null) // 被依赖的任务还未完成
- return false;
- if (result == null) { // 被依赖的任务完成了
- try {
- if (c != null && !c.claim()) // 判断任务是否能被执行
- return false;
- if (r instanceof AltResult) { // 判断异常,AltResult类型很简单,里面只有一个属性Throwable ex;
- x = ((AltResult) r).ex;
- t = null;
- } else {
- @SuppressWarnings("unchecked")
- T tr = (T) r; // 正常的结果
- t = tr;
- }
- f.accept(t, x); // 执行任务
- if (x == null) {
- internalComplete(r); // 任务的结果设置为被依赖任务的结果
- return true;
- }
- } catch (Throwable ex) {
- if (x == null)
- x = ex; // 记录异常
- }
- completeThrowable(x, r); // 设置异常和结果
- }
- return true;
- }
push()
- final void push(UniCompletion<?, ?> c) {
- if (c != null) {
- while (result == null && !tryPushStack(c))
- lazySetNext(c, null); // 失败重置c的next域
- }
- }
- final boolean tryPushStack(Completion c) {
- Completion h = stack;
- lazySetNext(c, h);
- return UNSAFE.compareAndSwapObject(this, STACK, h, c);
- }
- static void lazySetNext(Completion c, Completion next) {
- UNSAFE.putOrderedObject(c, NEXT, next);
- }
UniWhenComplete
- static final class UniWhenComplete<T> extends UniCompletion<T, T> {
- BiConsumer<? super T, ? super Throwable> fn;
- UniWhenComplete(Executor executor, CompletableFuture<T> dep, CompletableFuture<T> src,
- BiConsumer<? super T, ? super Throwable> fn) {
- super(executor, dep, src);
- this.fn = fn;
- }
- final CompletableFuture<T> tryFire(int mode) { // 钩子方法
- CompletableFuture<T> d; // 依赖的任务
- CompletableFuture<T> a; // 被依赖的任务
- if ((d = dep) == null || !d.uniWhenComplete(a = src, fn, mode > 0 ? null : this)) // 如果是异步模式(mode = 1),就不判断任务是否结束
- return null; // dep为空,说明已经调用过了
- dep = null;
- src = null;
- fn = null;
- return d.postFire(a, mode); // 钩子方法之后的处理
- }
- }
postFire(CompletableFuture<?> a, int mode)
- final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
- if (a != null && a.stack != null) { // 被依赖的任务存在,且stack不为空,先处理它
- if (mode < 0 || a.result == null) // 如果是嵌套模式(mode = -1), 或者任务的结果为空,直接清空栈
- a.cleanStack();
- else
- a.postComplete(); // 否则,调用postComplete()方法
- }
- if (result != null && stack != null) { // 再处理当前任务
- if (mode < 0) // 嵌套模式,直接返回自身(树 -> 链表,避免过深的递归调用)
- return this;
- else
- postComplete(); // 调用postComplete()方法
- }
- return null;
- }
cleanStack()
- final void cleanStack() { // 过滤掉已经死掉的结点(Not isLive)
- for (Completion p = null, q = stack; q != null;) { // q指针从头节点开始,向右移动,s一直执行q的下一个结点,p要么为空,要么指向遍历过的最后一个活着的结点,一旦发现q死掉了,就断开q, 连接p, s
- Completion s = q.next;
- if (q.isLive()) { // 还活着,p指向遍历过的最后一个结点,q向右移动
- p = q;
- q = s;
- } else if (p == null) { // 说明第一个结点就是死掉的,cas stack, q指向stack
- casStack(q, s);
- q = stack;
- } else { // 否则的话,连接p, s
- p.next = s;
- if (p.isLive()) // 再次判断p结点是否还或者(在这期间是否有别的线程改动了)
- q = s; // 还活着,q继续向右移动
- else {
- p = null; // 过期的值,从新开始
- q = stack;
- }
- }
- }
- }
如下图
1. 第1个结点是无效结点,更新stack,更新指针
2. 第2个结点是有效结点,更新指针
3. 第3个结点是无效结点,更新指针
4. 第4个结点是有效结点,更新指针
thenApply
- public <U> CompletableFuture<U> thenApply(Function<? super T, ? extends U> fn) {
- return uniApplyStage(null, fn);
- }
- 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;
- }
- 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;
- }
- static final class UniApply<T, V> extends UniCompletion<T, V> {
- Function<? super T, ? extends V> fn;
- UniApply(Executor executor, CompletableFuture<V> dep, CompletableFuture<T> src,
- Function<? super T, ? extends V> fn) {
- super(executor, dep, src);
- this.fn = fn;
- }
- 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);
- }
- }
一样的套路,thenApply/thenApplyAsync -> uniApplyStage -> uniApply -> tryFire -> postFire
thenAccept
- public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
- return uniAcceptStage(null, action);
- }
- public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) {
- return uniAcceptStage(asyncPool, action);
- }
- private CompletableFuture<Void> uniAcceptStage(Executor e, Consumer<? super T> f) {
- if (f == null)
- throw new NullPointerException();
- CompletableFuture<Void> d = new CompletableFuture<Void>();
- if (e != null || !d.uniAccept(this, f, null)) {
- UniAccept<T> c = new UniAccept<T>(e, d, this, f);
- push(c);
- c.tryFire(SYNC);
- }
- return d;
- }
- final <S> boolean uniAccept(CompletableFuture<S> a, Consumer<? super S> f, UniAccept<S> 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;
- f.accept(s);
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
- static final class UniAccept<T> extends UniCompletion<T, Void> {
- Consumer<? super T> fn;
- UniAccept(Executor executor, CompletableFuture<Void> dep, CompletableFuture<T> src, Consumer<? super T> fn) {
- super(executor, dep, src);
- this.fn = fn;
- }
- final CompletableFuture<Void> tryFire(int mode) {
- CompletableFuture<Void> d;
- CompletableFuture<T> a;
- if ((d = dep) == null || !d.uniAccept(a = src, fn, mode > 0 ? null : this))
- return null;
- dep = null;
- src = null;
- fn = null;
- return d.postFire(a, mode);
- }
- }
thenAccept/thenAcceptAsync -> uniAcceptStage -> uniAccept -> tryFire -> postFire
thenRun
- public CompletableFuture<Void> thenRun(Runnable action) {
- return uniRunStage(null, action);
- }
- public CompletableFuture<Void> thenRunAsync(Runnable action) {
- return uniRunStage(asyncPool, action);
- }
- private CompletableFuture<Void> uniRunStage(Executor e, Runnable f) {
- if (f == null)
- throw new NullPointerException();
- CompletableFuture<Void> d = new CompletableFuture<Void>();
- if (e != null || !d.uniRun(this, f, null)) {
- UniRun<T> c = new UniRun<T>(e, d, this, f);
- push(c);
- c.tryFire(SYNC);
- }
- return d;
- }
- final boolean uniRun(CompletableFuture<?> a, Runnable f, UniRun<?> c) {
- Object r;
- Throwable x;
- if (a == null || (r = a.result) == null || f == null)
- return false;
- if (result == null) {
- if (r instanceof AltResult && (x = ((AltResult) r).ex) != null)
- completeThrowable(x, r);
- else
- try {
- if (c != null && !c.claim())
- return false;
- f.run();
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
- static final class UniRun<T> extends UniCompletion<T, Void> {
- Runnable fn;
- UniRun(Executor executor, CompletableFuture<Void> dep, CompletableFuture<T> src, Runnable fn) {
- super(executor, dep, src);
- this.fn = fn;
- }
- final CompletableFuture<Void> tryFire(int mode) {
- CompletableFuture<Void> d;
- CompletableFuture<T> a;
- if ((d = dep) == null || !d.uniRun(a = src, fn, mode > 0 ? null : this))
- return null;
- dep = null;
- src = null;
- fn = null;
- return d.postFire(a, mode);
- }
- }
thenRun/thenRunAsync -> uniRunStage -> uniRun -> tryFire -> postFire
thenAcceptBoth
thenAcceptBoth
- public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other,
- BiConsumer<? super T, ? super U> action) {
- return biAcceptStage(null, other, action);
- }
- public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,
- BiConsumer<? super T, ? super U> action) {
- return biAcceptStage(asyncPool, other, action);
- }
biAcceptStage
- private <U> CompletableFuture<Void> biAcceptStage(Executor e, CompletionStage<U> o,
- BiConsumer<? super T, ? super U> f) {
- CompletableFuture<U> b;
- if (f == null || (b = o.toCompletableFuture()) == null)
- throw new NullPointerException();
- CompletableFuture<Void> d = new CompletableFuture<Void>();
- if (e != null || !d.biAccept(this, b, f, null)) {
- BiAccept<T, U> c = new BiAccept<T, U>(e, d, this, b, f);
- bipush(b, c);
- c.tryFire(SYNC);
- }
- return d;
- }
bipush
- final void bipush(CompletableFuture<?> b, BiCompletion<?, ?, ?> c) {
- if (c != null) {
- Object r;
- while ((r = result) == null && !tryPushStack(c)) // a的result还没准备好,c压入栈
- lazySetNext(c, null); // 失败重置c的next域
- if (b != null && b != this && b.result == null) { // b的result也还没准备好
- Completion q = (r != null) ? c : new CoCompletion(c); // 根据a的result决定是否构建CoCompletion, 如果a未结束,则构建一个CoCompletion, CoCompletion最后调用的也是BiCompletion的tryFire
- while (b.result == null && !b.tryPushStack(q)) // 将q压入栈
- lazySetNext(q, null); // 失败重置q的next域
- }
- }
- }
CoCompletion
- static final class CoCompletion extends Completion {
- BiCompletion<?, ?, ?> base;
- CoCompletion(BiCompletion<?, ?, ?> base) {
- this.base = base;
- }
- final CompletableFuture<?> tryFire(int mode) {
- BiCompletion<?, ?, ?> c;
- CompletableFuture<?> d;
- if ((c = base) == null || (d = c.tryFire(mode)) == null) // 调用的还是BiCompletion的tryFire方法
- return null;
- base = null;
- return d;
- }
- final boolean isLive() {
- BiCompletion<?, ?, ?> c;
- return (c = base) != null && c.dep != null;
- }
- }
biAccept
- final <R, S> boolean biAccept(CompletableFuture<R> a, CompletableFuture<S> b, BiConsumer<? super R, ? super S> f,
- BiAccept<R, S> c) {
- Object r, s;
- Throwable x;
- if (a == null || (r = a.result) == null || b == null || (s = b.result) == null || f == null)
- return false; // a和b都完成了,才会往下走
- tryComplete: if (result == null) {
- if (r instanceof AltResult) {
- if ((x = ((AltResult) r).ex) != null) { // a的异常检查
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- if (s instanceof AltResult) {
- if ((x = ((AltResult) s).ex) != null) { // b的异常检查
- completeThrowable(x, s);
- break tryComplete;
- }
- s = null;
- }
- try {
- if (c != null && !c.claim())
- return false;
- @SuppressWarnings("unchecked")
- R rr = (R) r;
- @SuppressWarnings("unchecked")
- S ss = (S) s;
- f.accept(rr, ss); // 执行任务
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
BiAccept
- static final class BiAccept<T, U> extends BiCompletion<T, U, Void> {
- BiConsumer<? super T, ? super U> fn;
- BiAccept(Executor executor, CompletableFuture<Void> dep, CompletableFuture<T> src, CompletableFuture<U> snd,
- BiConsumer<? super T, ? super U> fn) {
- super(executor, dep, src, snd);
- this.fn = fn;
- }
- final CompletableFuture<Void> tryFire(int mode) {
- CompletableFuture<Void> d;
- CompletableFuture<T> a;
- CompletableFuture<U> b;
- if ((d = dep) == null || !d.biAccept(a = src, b = snd, fn, mode > 0 ? null : this))
- return null;
- dep = null;
- src = null;
- snd = null;
- fn = null;
- return d.postFire(a, b, mode);
- }
- }
- abstract static class BiCompletion<T, U, V> extends UniCompletion<T, V> {
- CompletableFuture<U> snd; // second source for action
- BiCompletion(Executor executor, CompletableFuture<V> dep, CompletableFuture<T> src, CompletableFuture<U> snd) {
- super(executor, dep, src);
- this.snd = snd;
- }
- }
thenAcceptBoth/thenAcceptBothAsync -> biAcceptStage -> biAccept -> tryFire -> postFire
acceptEither
- public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action) {
- return orAcceptStage(null, other, action);
- }
- public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action) {
- return orAcceptStage(asyncPool, other, action);
- }
- private <U extends T> CompletableFuture<Void> orAcceptStage(Executor e, CompletionStage<U> o,
- Consumer<? super T> f) {
- CompletableFuture<U> b;
- if (f == null || (b = o.toCompletableFuture()) == null)
- throw new NullPointerException();
- CompletableFuture<Void> d = new CompletableFuture<Void>();
- if (e != null || !d.orAccept(this, b, f, null)) {
- OrAccept<T, U> c = new OrAccept<T, U>(e, d, this, b, f);
- orpush(b, c);
- c.tryFire(SYNC);
- }
- return d;
- }
- final <R, S extends R> boolean orAccept(CompletableFuture<R> a, CompletableFuture<S> b, Consumer<? super R> f,
- OrAccept<R, S> c) {
- Object r;
- Throwable x;
- if (a == null || b == null || ((r = a.result) == null && (r = b.result) == null) || f == null)
- return false; // a和b有一个完成了就往下走
- tryComplete: if (result == null) {
- try {
- if (c != null && !c.claim())
- return false;
- if (r instanceof AltResult) { // 异常
- if ((x = ((AltResult) r).ex) != null) {
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- @SuppressWarnings("unchecked")
- R rr = (R) r;
- f.accept(rr); // 执行
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
- static final class OrAccept<T, U extends T> extends BiCompletion<T, U, Void> {
- Consumer<? super T> fn;
- OrAccept(Executor executor, CompletableFuture<Void> dep, CompletableFuture<T> src, CompletableFuture<U> snd,
- Consumer<? super T> fn) {
- super(executor, dep, src, snd);
- this.fn = fn;
- }
- final CompletableFuture<Void> tryFire(int mode) {
- CompletableFuture<Void> d;
- CompletableFuture<T> a;
- CompletableFuture<U> b;
- if ((d = dep) == null || !d.orAccept(a = src, b = snd, fn, mode > 0 ? null : this))
- return null;
- dep = null;
- src = null;
- snd = null;
- fn = null;
- return d.postFire(a, b, mode);
- }
- }
- final void orpush(CompletableFuture<?> b, BiCompletion<?, ?, ?> c) {
- if (c != null) {
- while ((b == null || b.result == null) && result == null) { // a和b的result都没好,才会考虑入栈
- if (tryPushStack(c)) { // 先入a的栈
- if (b != null && b != this && b.result == null) { // 入a的栈成功,b的result还没好
- Completion q = new CoCompletion(c); // a还未结束,用c构建CoCompletion
- while (result == null && b.result == null && !b.tryPushStack(q)) // 再次判断,a和b的result都没好,才会考虑入栈
- lazySetNext(q, null); // 失败置空q的next域
- }
- break;
- }
- lazySetNext(c, null); // 失败置空c的next域
- }
- }
- }
acceptEither/acceptEitherAsync -> orAcceptStage -> orAccept -> tryFire -> postFire
allOf
- public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {
- return andTree(cfs, 0, cfs.length - 1);
- }
- static CompletableFuture<Void> andTree(CompletableFuture<?>[] cfs, int lo, int hi) { // 将一个数组构建成一棵树,二叉树,动态规划
- CompletableFuture<Void> d = new CompletableFuture<Void>();
- if (lo > hi) // empty
- d.result = NIL;
- else {
- CompletableFuture<?> a, b;
- int mid = (lo + hi) >>> 1;
- if ((a = (lo == mid ? cfs[lo] : andTree(cfs, lo, mid))) == null
- || (b = (lo == hi ? a : (hi == mid + 1) ? cfs[hi] : andTree(cfs, mid + 1, hi))) == null)
- throw new NullPointerException();
- if (!d.biRelay(a, b)) {
- BiRelay<?, ?> c = new BiRelay<>(d, a, b);
- a.bipush(b, c); // both
- c.tryFire(SYNC);
- }
- }
- return d;
- }
- static final class BiRelay<T, U> extends BiCompletion<T, U, Void> { // for And
- BiRelay(CompletableFuture<Void> dep, CompletableFuture<T> src, CompletableFuture<U> snd) {
- super(null, dep, src, snd);
- }
- final CompletableFuture<Void> tryFire(int mode) {
- CompletableFuture<Void> d;
- CompletableFuture<T> a;
- CompletableFuture<U> b;
- if ((d = dep) == null || !d.biRelay(a = src, b = snd))
- return null;
- src = null;
- snd = null;
- dep = null;
- return d.postFire(a, b, mode);
- }
- }
- boolean biRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
- Object r, s;
- Throwable x;
- if (a == null || (r = a.result) == null || b == null || (s = b.result) == null)
- return false; // a和b都结束了才往下执行
- if (result == null) {
- if (r instanceof AltResult && (x = ((AltResult) r).ex) != null)
- completeThrowable(x, r);
- else if (s instanceof AltResult && (x = ((AltResult) s).ex) != null)
- completeThrowable(x, s);
- else
- completeNull(); // 辅助结点,什么都不做
- }
- return true;
- }
allOf -> andTree -> biRelay -> tryFire -> postFire
anyOf
- public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
- return orTree(cfs, 0, cfs.length - 1);
- }
- static CompletableFuture<Object> orTree(CompletableFuture<?>[] cfs, int lo, int hi) { // 将一个数组构建成一棵树,二叉树,动态规划
- CompletableFuture<Object> d = new CompletableFuture<Object>();
- if (lo <= hi) {
- CompletableFuture<?> a, b;
- int mid = (lo + hi) >>> 1;
- if ((a = (lo == mid ? cfs[lo] : orTree(cfs, lo, mid))) == null
- || (b = (lo == hi ? a : (hi == mid + 1) ? cfs[hi] : orTree(cfs, mid + 1, hi))) == null)
- throw new NullPointerException();
- if (!d.orRelay(a, b)) {
- OrRelay<?, ?> c = new OrRelay<>(d, a, b);
- a.orpush(b, c);
- c.tryFire(SYNC);
- }
- }
- return d;
- }
- static final class OrRelay<T, U> extends BiCompletion<T, U, Object> { // for Or
- OrRelay(CompletableFuture<Object> dep, CompletableFuture<T> src, CompletableFuture<U> snd) {
- super(null, dep, src, snd);
- }
- final CompletableFuture<Object> tryFire(int mode) {
- CompletableFuture<Object> d;
- CompletableFuture<T> a;
- CompletableFuture<U> b;
- if ((d = dep) == null || !d.orRelay(a = src, b = snd))
- return null;
- src = null;
- snd = null;
- dep = null;
- return d.postFire(a, b, mode);
- }
- }
- final boolean orRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
- Object r;
- if (a == null || b == null || ((r = a.result) == null && (r = b.result) == null))
- return false; // a和b有一个结束就往下进行
- if (result == null)
- completeRelay(r);
- return true;
- }
anyOf -> orTree -> orRelay -> tryFire -> postFire
数组构建树
allOf和anyOf都用到了数组构建成树的策略。
假设有一个任务Z(虚拟的,什么都不做),依赖一组任务[A, B, C, D, E, F, G, H]
对于allOf, 当这组任务都完成时,才会执行Z;对于anyOf, 当这组任务中有任何一个完成,就执行任务Z。
如果这组任务是数组结构或者链表结构,我们该如何解决呢?遍历数组或者是链表,当任务都完成或者有一个完成时,就执行Z,需要不停地遍历,这是轮询的方法,不合适。
整个基调是回调,是指,当一个任务完成时,会接着执行所有依赖于它的任务。
作为一个数组或者链表,该如何应用回调呢?谁在先,谁在后呢?因为不知道哪个任务会先完成,所以没法确定次序。而且这组任务之间也不应该相互依赖,它们只不过都是被Z依赖。
如果这组任务只有一个的话,那就演变成了X.thenXXX(Z), 如果这组任务有两个的话,allOf -> Both,anyOf -> Either
如果Z依赖Z1,Z2两个个任务,Z1和Z2依赖Z11,Z12和Z21,Z22四个任务,依次类推,当虚拟的任务的个数达到真实任务的个数的一半时,就让虚拟任务监听真实的任务,动态规划加二叉树,时间复杂度也只是logn级别的。
- static String array2Tree(String[] cfs, int lo, int hi) {
- String d = new String(cfs[lo] + cfs[hi]);
- if (lo <= hi) {
- String a, b;
- int mid = (lo + hi) >>> 1; // 二分
- if (lo == mid) { // a作为左半部分的的结果
- a = cfs[lo]; // 当只有不超过两个元素时,a直接取第一个值
- } else {
- a = array2Tree(cfs, lo, mid);
- }
- if (lo == hi) { // 当只有一个元素的时候,b取a的值
- b = a;
- } else {
- if (hi == mid + 1) { // 右半部分只有两个元素时,b取第二个元素的值
- b = cfs[hi];
- } else {
- b = array2Tree(cfs, mid + 1, hi);
- }
- }
- if (a == null || b == null) {
- throw new NullPointerException();
- }
- System.out.println("[" + a + "][" + b + "]->[" + d + "]");
- }
- return d;
- }
Console
- [A][B]->[AB]
- [C][D]->[CD]
- [AB][CD]->[AD]
- [E][F]->[EF]
- [G][H]->[GH]
- [EF][GH]->[EH]
- [AD][EH]->[AH]
如下图
对于allOf, Z只要保证Z1和Z2都完成了就行,Z1和Z2分别保证Z11,Z12 和 Z21,Z22都完成了就像,而Z11,Z12,Z21,Z22则分别保证了A-H任务都完成。
对应anyOf, Z 只要保证Z1和Z2有一个完成了就像,Z1和Z2联合保证了Z11,Z12,Z21,Z22这4个任务只要有一个完成了就行,同理,Z11,Z12,Z21,Z22则联合保证了A-H中有一个任务完成了就行。
然后,Z就可以执行了,其实Z什么也没做,只是从这组任务里得出一个结果。
行文至此结束。
尊重他人的劳动,转载请注明出处:http://www.cnblogs.com/aniao/p/aniao_cf.html
【JUC源码解析】CompletableFuture的更多相关文章
- 【JUC源码解析】ScheduledThreadPoolExecutor
简介 它是一个线程池执行器(ThreadPoolExecutor),在给定的延迟(delay)后执行.在多线程或者对灵活性有要求的环境下,要优于java.util.Timer. 提交的任务在执行之前支 ...
- 【JUC源码解析】SynchronousQueue
简介 SynchronousQueue是一种特殊的阻塞队列,该队列没有容量. [存数据线程]到达队列后,若发现没有[取数据线程]在此等待,则[存数据线程]便入队等待,直到有[取数据线程]来取数据,并释 ...
- 【JUC源码解析】ForkJoinPool
简介 ForkJoin 框架,另一种风格的线程池(相比于ThreadPoolExecutor),采用分治算法,工作密取策略,极大地提高了并行性.对于那种大任务分割小任务的场景(分治)尤其有用. 框架图 ...
- 【JUC源码解析】DelayQueue
简介 基于优先级队列,以过期时间作为排序的基准,剩余时间最少的元素排在队首.只有过期的元素才能出队,在此之前,线程等待. 源码解析 属性 private final transient Reentra ...
- 【JUC源码解析】CyclicBarrier
简介 CyclicBarrier,一个同步器,允许多个线程相互等待,直到达到一个公共屏障点. 概述 CyclicBarrier支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后 ...
- 【JUC源码解析】ConcurrentLinkedQueue
简介 ConcurrentLinkedQueue是一个基于链表结点的无界线程安全队列. 概述 队列顺序,为FIFO(first-in-first-out):队首元素,是当前排队时间最长的:队尾元素,当 ...
- 【JUC源码解析】Exchanger
简介 Exchanger,并发工具类,用于线程间的数据交换. 使用 两个线程,两个缓冲区,一个线程往一个缓冲区里面填数据,另一个线程从另一个缓冲区里面取数据.当填数据的线程将缓冲区填满时,或者取数据的 ...
- Jdk1.6 JUC源码解析(12)-ArrayBlockingQueue
功能简介: ArrayBlockingQueue是一种基于数组实现的有界的阻塞队列.队列中的元素遵循先入先出(FIFO)的规则.新元素插入到队列的尾部,从队列头部取出元素. 和普通队列有所不同,该队列 ...
- Jdk1.6 JUC源码解析(13)-LinkedBlockingQueue
功能简介: LinkedBlockingQueue是一种基于单向链表实现的有界的(可选的,不指定默认int最大值)阻塞队列.队列中的元素遵循先入先出 (FIFO)的规则.新元素插入到队列的尾部,从队列 ...
随机推荐
- dubbo-admin管理控制台的安装部署(最简单)
Dubbo-admin最简单的安装部署,十分钟就能搞定! 网上找的安装教程虽说详细,但是就是因为详细操作起来而显得繁琐.今天,我帮大家跳过这些繁琐的步骤,简单快捷的安装部署dubbo-admin. 1 ...
- Scala学习笔记2 (带着问题学习, 逐渐扩展。理解吃透scala.)
问题: 把 文本字符串"[1, 2, 3, 4, 5]" 转换成一个数组. 答案: val x = "[1, 2, 3, 4, 5]" val y =x sli ...
- [20171225]RMAN-06808: SECTION SIZE cannot be used when piece limit is in effect.txt
[20171225]RMAN-06808: SECTION SIZE cannot be used when piece limit is in effect.txt --//朋友拿我的一些例子来测试 ...
- Sql Server 判断字符串是否可以转数字
主要是在sql server的内置系统函数ISNUMERIC的基础上,将例外的“+”.“-”.“$”等也进行判断. CREATE FUNCTION [dbo].[fn_IsNumberic]( @st ...
- c# 百度地图api APP SN校验失败
在使用c#调用百度地图Web服务api遇到的签名(sn校验)问题,在此记录一下,(ip白名单校验的请忽略) 1.首先获取ak与sk,这个两个东西可以从控制台中获取到 2.在这个地址:sn签名算法,里面 ...
- Sublime Text 3 注册码激活码被移除的解决办法
新版的sublime text3中加入了验证功能,之前成功注册的也被移除了,在网上搜索的验证码要么已经失效要么已经被封,少数几个正常的注册输入进去注册成功后几分钟之内这个注册码就会被莫名其妙的被移除. ...
- table表格(笔记)
<table class="table table-hover2 pick_carTable"> <thead> <tr class="bl ...
- C++中int型与string型互相转换(转)
http://greatverve.cnblogs.com/archive/2012/10/24/cpp-int-string.html 本以为这么多年C#经验,学个C++没多难,现在发现错了.C++ ...
- Weblogic读不到Word文件
之前遇到一导出word文件的需求,我的做法是把对应导出内容放到一个word文件中,把其中变化的内容作为变量,然后把该word文件放在WEB-INF目录下用来作为模板.在导出时通过ServletCont ...
- BZOJ1006:[HNOI2008]神奇的国度(弦图染色)
Description K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的. 为了巩固三角关系,K国禁止四边关系,五边关 ...