CompletableFuture 底层原理详解

一、核心设计思想

1.1 无锁并发设计

CompletableFuture 采用了 无锁(Lock-Free)并发设计,主要依靠以下机制:

  • CAS(Compare-And-Swap):原子操作更新状态

  • volatile 变量:保证内存可见性

  • Treiber 栈:用于管理依赖关系

  • 优化线程竞争:减少同步开销

1.2 异步回调机制

java 复制代码
// 回调机制的抽象
interface Completion {
    void tryFire(int mode);  // 触发执行
    CompletableFuture<?> src; // 源 Future
    CompletableFuture<?> dep; // 依赖的 Future
}

二、核心数据结构

2.1 状态表示

java 复制代码
// 内部状态字段(简化版)
public class CompletableFuture<T> {
    volatile Object result;    // 结果或异常
    volatile Completion stack; // 依赖栈(Treiber Stack)
    
    // 结果类型标记(通过对象引用类型区分)
    static final AltResult NIL = new AltResult(null); // 空结果
    static final class AltResult {
        final Throwable ex; // 异常或 null
        AltResult(Throwable ex) { this.ex = ex; }
    }
}

2.2 Completion 层次结构

java 复制代码
// 回调抽象类(关键数据结构)
abstract static class Completion extends ForkJoinTask<Void>
    implements Runnable, AsynchronousCompletionTask {
    
    volatile Completion next; // 栈中的下一个节点
    
    // 执行回调
    abstract void tryFire(int mode);
    abstract boolean isLive();
}

// 各种具体实现
static final class UniCompletion<T,V> extends Completion {
    Executor executor;          // 执行器
    CompletableFuture<V> dep;   // 依赖的 Future
    CompletableFuture<T> src;   // 源 Future
    BiFunction<? super T, Throwable, ? extends V> fn; // 转换函数
    
    void tryFire(int mode) { /* 具体实现 */ }
}

static final class BiCompletion<T,U,V> extends Completion {
    // 用于两个源的情况(thenCombine, thenAcceptBoth等)
}

static final class OrCompletion extends Completion {
    // 用于 anyOf 操作
}

2.3 Treiber 栈实现

java 复制代码
// Treiber 栈:无锁栈实现
class CompletionStack {
    private volatile Completion top;
    
    // 压栈(CAS 操作)
    boolean push(Completion c) {
        Completion oldTop;
        do {
            oldTop = top;
            c.next = oldTop;
        } while (!UNSAFE.compareAndSwapObject(
            this, TOP_OFFSET, oldTop, c));
        return oldTop == null;
    }
    
    // 弹栈
    Completion pop() {
        Completion oldTop;
        do {
            oldTop = top;
            if (oldTop == null) return null;
            Completion newTop = oldTop.next;
        } while (!UNSAFE.compareAndSwapObject(
            this, TOP_OFFSET, oldTop, newTop));
        return oldTop;
    }
}

三、执行流程详解

3.1 任务提交与执行

java 复制代码
public class CompletableFuture<T> {
    
    // 异步提交任务
    public static <U> CompletableFuture<U> supplyAsync(
            Supplier<U> supplier, Executor executor) {
        
        CompletableFuture<U> f = new CompletableFuture<>();
        
        // 将任务包装成 AsyncSupply
        AsyncSupply<U> a = new AsyncSupply<>(f, supplier);
        
        // 提交到线程池
        executor.execute(a);
        
        return f;
    }
    
    // AsyncSupply 内部类
    static final class AsyncSupply<T> extends ForkJoinTask<Void>
        implements Runnable, AsynchronousCompletionTask {
        
        CompletableFuture<T> dep; // 依赖的 Future
        Supplier<T> fn;           // 用户函数
        
        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 {
                        // 执行用户函数
                        T value = f.get();
                        // 设置结果
                        d.completeValue(value);
                    } catch (Throwable ex) {
                        // 设置异常
                        d.completeThrowable(ex);
                    }
                }
                // 清理引用
                d.postComplete();
            }
        }
    }
}

3.2 结果完成机制

java 复制代码
// 完成结果的核心方法
final boolean completeValue(T t) {
    // 使用 CAS 设置结果,保证原子性
    return UNSAFE.compareAndSwapObject(
        this, RESULT_OFFSET, null, 
        (t == null) ? NIL : t);
}

// 完成异常
final boolean completeThrowable(Throwable x) {
    return UNSAFE.compareAndSwapObject(
        this, RESULT_OFFSET, null, 
        new AltResult(x));
}

// 完成后的处理
final void postComplete() {
    CompletableFuture<?> f = this;
    Completion h;
    
    // 循环处理栈中的所有 Completion
    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; // 断开链接
            }
            // 触发回调
            f = (d = h.tryFire(NESTED)) == null ? this : d;
        }
    }
}

四、回调链机制

4.1 回调链的构建

java 复制代码
public class CompletableFuture<T> {
    
    // thenApply 的实现
    public <U> CompletableFuture<U> thenApply(
            Function<? super T,? extends U> fn) {
        return uniApplyStage(null, 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<>();
        
        // 如果源已经完成,立即执行
        if (e != null || !d.uniApply(this, f, null)) {
            // 否则创建 UniApply 节点并压栈
            UniApply<T,V> c = new UniApply<>(e, d, this, f);
            push(c);  // 压入依赖栈
            c.tryFire(SYNC);  // 尝试触发
        }
        return d;
    }
    
    // UniApply 节点的实现
    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);
        }
    }
}

4.2 异步传播机制

java 复制代码
// 任务完成后触发依赖链
private void postComplete() {
    CompletableFuture<?> f = this;
    Completion h;
    
    // 不断处理栈中的 Completion
    while ((h = f.stack) != null) {
        CompletableFuture<?> d;
        Completion t;
        
        // CAS 弹栈
        if (f.casStack(h, t = h.next)) {
            if (t != null) {
                // 处理栈重组
                if (f != this) {
                    pushStack(h);
                    continue;
                }
                h.next = null;
            }
            
            // 触发当前 Completion
            f = (d = h.tryFire(NESTED)) == null ? this : d;
        }
    }
}

五、线程池与执行器

5.1 默认线程池

java 复制代码
// CompletableFuture 的默认执行器
public class CompletableFuture<T> {
    
    // 默认使用 ForkJoinPool
    private static final Executor ASYNC_POOL;
    
    static {
        // 尝试使用 CommonPool,否则创建新线程
        if (ForkJoinPool.getCommonPoolParallelism() > 1)
            ASYNC_POOL = ForkJoinPool.commonPool();
        else
            ASYNC_POOL = new ThreadPerTaskExecutor();
    }
    
    // 每个任务一个线程的执行器(fallback)
    static final class ThreadPerTaskExecutor implements Executor {
        public void execute(Runnable r) {
            new Thread(r).start();
        }
    }
}

5.2 执行模式

java 复制代码
// 三种执行模式
static final int SYNC   =  0;  // 同步执行(当前线程)
static final int ASYNC  =  1;  // 异步执行(线程池)
static final int NESTED = -1;  // 嵌套执行(避免栈溢出)

六、组合操作实现

6.1 allOf 实现

java 复制代码
static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {
    return andTree(cfs, 0, cfs.length - 1);
}

private static CompletableFuture<Void> andTree(
        CompletableFuture<?>[] cfs, int lo, int hi) {
    
    CompletableFuture<Void> d = new CompletableFuture<>();
    
    if (lo > hi) { // 空数组
        d.result = NIL;
    } else {
        CompletableFuture<?> a, b;
        
        // 递归构建二叉树
        int mid = (lo + hi) >>> 1;
        if ((a = (lo == mid ? cfs[lo] :
                 andTree(cfs, lo, mid))) == null ||
            (b = (mid == hi ? cfs[hi] :
                 andTree(cfs, mid + 1, hi))) == null)
            throw new NullPointerException();
        
        // 创建 BiRelay 来等待两个 Future
        if (!d.biRelay(a, b)) {
            BiRelay<?,?> c = new BiRelay<>(d, a, b);
            a.bipush(b, c);
            c.tryFire(SYNC);
        }
    }
    return d;
}

// BiRelay:等待两个 Future 完成
static final class BiRelay<T,U> extends BiCompletion<T,U,Void> {
    BiRelay(CompletableFuture<Void> dep,
            CompletableFuture<T> src1,
            CompletableFuture<U> src2) {
        super(null, dep, src1, src2);
    }
    
    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);
    }
}

6.2 anyOf 实现

java 复制代码
static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
    return orTree(cfs, 0, cfs.length - 1);
}

private static CompletableFuture<Object> orTree(
        CompletableFuture<?>[] cfs, int lo, int hi) {
    
    CompletableFuture<Object> d = new CompletableFuture<>();
    
    if (lo <= hi) {
        CompletableFuture<?> a, b;
        
        // 类似于 allOf 的二叉树构建
        int mid = (lo + hi) >>> 1;
        if ((a = (lo == mid ? cfs[lo] :
                 orTree(cfs, lo, mid))) == null ||
            (b = (mid == hi ? cfs[hi] :
                 orTree(cfs, mid + 1, hi))) == null)
            throw new NullPointerException();
        
        // 创建 OrRelay
        if (!d.orRelay(a, b)) {
            OrRelay c = new OrRelay(d, a, b);
            a.orpush(b, c);
            c.tryFire(SYNC);
        }
    }
    return d;
}

七、内存模型与可见性

7.1 内存屏障

java 复制代码
// 使用 Unsafe 保证内存可见性
private static final sun.misc.Unsafe UNSAFE;
private static final long RESULT_OFFSET;
private static final long STACK_OFFSET;
private static final long NEXT_OFFSET;

static {
    try {
        UNSAFE = sun.misc.Unsafe.getUnsafe();
        Class<?> k = CompletableFuture.class;
        
        // 获取字段偏移量
        RESULT_OFFSET = UNSAFE.objectFieldOffset(
            k.getDeclaredField("result"));
        STACK_OFFSET = UNSAFE.objectFieldOffset(
            k.getDeclaredField("stack"));
        
        Class<?> ak = Completion.class;
        NEXT_OFFSET = UNSAFE.objectFieldOffset(
            ak.getDeclaredField("next"));
    } catch (Exception e) {
        throw new Error(e);
    }
}

// CAS 操作保证原子性
final boolean casStack(Completion cmp, Completion val) {
    return UNSAFE.compareAndSwapObject(this, STACK_OFFSET, cmp, val);
}

final boolean casResult(Object cmp, Object val) {
    return UNSAFE.compareAndSwapObject(this, RESULT_OFFSET, cmp, val);
}

7.2 Happens-Before 关系

java 复制代码
// 重要的 happens-before 关系:
// 1. 线程 A 执行 complete() → 线程 B 看到结果
// 2. 回调函数的执行顺序符合依赖关系
// 3. 异步任务的提交 happens-before 其执行

// 示例:保证可见性
public T get() throws InterruptedException, ExecutionException {
    Object r;
    
    // 自旋等待结果
    while ((r = result) == null) {
        // 使用 Unsafe 的读屏障
        UNSAFE.loadFence();
        
        // 检查中断
        if (Thread.interrupted())
            throw new InterruptedException();
        
        // 短暂休眠避免忙等
        Thread.yield();
    }
    
    // 返回结果(结果已可见)
    return reportGet(r);
}

八、异常处理机制

8.1 异常传播

java 复制代码
// 异常封装
static final class AltResult {
    final Throwable ex; // 存储异常
    AltResult(Throwable ex) { this.ex = ex; }
}

// 异常提取
private static Throwable encodeThrowable(Throwable x) {
    return (x instanceof CompletionException) ? x :
        new CompletionException(x);
}

// 异常传播到依赖链
final void completeThrowable(Throwable x, Object r) {
    if (result == null) {
        // CAS 设置异常结果
        if (UNSAFE.compareAndSwapObject(
            this, RESULT_OFFSET, null, 
            encodeThrowable(x))) {
            
            // 触发依赖链
            postComplete();
        }
    }
}

8.2 exceptionally 实现

java 复制代码
public CompletableFuture<T> exceptionally(
        Function<Throwable, ? extends T> fn) {
    
    return uniExceptionallyStage(fn);
}

private CompletableFuture<T> uniExceptionallyStage(
        Function<Throwable, ? extends T> f) {
    
    if (f == null) throw new NullPointerException();
    
    CompletableFuture<T> d = new CompletableFuture<>();
    
    // 如果已经完成且有异常,应用函数
    if (!d.uniExceptionally(this, f, null)) {
        // 否则创建 UniExceptionally 节点
        UniExceptionally<T> c = new UniExceptionally<>(d, this, f);
        push(c);
        c.tryFire(SYNC);
    }
    return d;
}

九、性能优化策略

9.1 避免栈溢出

java 复制代码
// 使用迭代而非递归处理长链
final void postComplete() {
    CompletableFuture<?> f = this;
    Completion h;
    
    while ((h = f.stack) != null) {
        // 迭代处理,避免递归导致的栈溢出
        if (f.casStack(h, h.next)) {
            // 处理当前节点
            f = (h.tryFire(NESTED) == null) ? this : h.dep;
        }
    }
}

9.2 延迟初始化

java 复制代码
// 按需创建线程池
private static Executor screenExecutor(Executor e) {
    if (e == null) {
        // 返回默认线程池
        return ASYNC_POOL;
    }
    return e;
}

// 延迟创建 Completion 节点
private <V> CompletableFuture<V> uniApplyStage(
        Executor e, Function<? super T,? extends V> f) {
    
    // 如果源已经完成,直接执行而不创建节点
    Object r;
    if ((r = result) != null) {
        try {
            // 同步执行转换
            V v = f.apply((T) r);
            return new CompletableFuture<V>().completeValue(v);
        } catch (Throwable ex) {
            return new CompletableFuture<V>().completeThrowable(ex);
        }
    }
    
    // 否则创建节点并压栈
    CompletableFuture<V> d = new CompletableFuture<>();
    UniApply<T,V> c = new UniApply<>(e, d, this, f);
    push(c);
    c.tryFire(SYNC);
    return d;
}

十、调试和监控

10.1 内部状态查看

java 复制代码
// 调试方法:查看内部状态
public String debugString() {
    StringBuilder sb = new StringBuilder();
    sb.append("CompletableFuture@").append(hashCode());
    sb.append("[result=").append(result);
    sb.append(", stackSize=").append(getStackSize());
    sb.append(", isDone=").append(isDone());
    sb.append(", isCompletedExceptionally=")
      .append(isCompletedExceptionally());
    sb.append("]");
    return sb.toString();
}

// 计算栈大小
private int getStackSize() {
    int size = 0;
    for (Completion c = stack; c != null; c = c.next) {
        size++;
    }
    return size;
}

总结

CompletableFuture 的底层原理可以概括为以下几点:

核心机制:

  1. 无锁并发:通过 CAS 和 volatile 实现高效并发控制

  2. 依赖栈:使用 Treiber 栈管理回调依赖关系

  3. 延迟执行:按需创建和执行回调节点

  4. 异步传播:结果或异常在依赖链中异步传播

关键优化:

  1. 内存高效:通过对象复用减少内存分配

  2. 线程池优化:智能选择执行线程

  3. 栈安全:避免长回调链导致的栈溢出

  4. 可见性保证:严格的内存屏障保证并发正确性

设计哲学:

  1. 函数式编程:支持链式调用和组合操作

  2. 事件驱动:基于回调的异步编程模型

  3. 资源友好:按需使用线程和内存资源

  4. 异常安全:完整的异常传播和处理机制

理解 CompletableFuture 的底层原理有助于:

  • 编写更高效的异步代码

  • 避免常见的并发陷阱

  • 调试复杂的异步问题

  • 设计高性能的并发系统

相关推荐
爱笑的眼睛112 小时前
神经网络的骨架:深入解析前向传播的数学本质与工程实现
java·人工智能·python·ai
就叫飞六吧2 小时前
pdf转国产ofd格式代码案例-Java
java·python·pdf
Yng Forever2 小时前
腾讯云人脸识别SDK集成
java·后端·云计算·腾讯云
LiamTuc2 小时前
Java 接口定义变量
java·开发语言
小坏讲微服务2 小时前
Spring Cloud Alibaba 微服务整合自定义日志注解完整教程
java·spring cloud·微服务·云原生·架构
赵得C3 小时前
软件设计师进阶知识点解析:分布式与数据应用考点精讲
java·开发语言·分布式·设计模式
雨中飘荡的记忆3 小时前
Docker与Java实战指南
java·docker·容器
是一个Bug3 小时前
声明式事务
java·开发语言·面试
妮妮喔妮3 小时前
Redis Cluster故障处理机制
java·数据库·redis