Future模式与Promise模式

#并发

总结
  • Future 模式:提交任务拿占位符,稍后 get() 或回调获取结果
  • CompletableFuture(JDK 8)是 Promise 模式,链式调用解决回调地狱,生产首选
  • 生产环境给 CompletableFuture 传自定义线程池,别用默认的 ForkJoinPool

核心概念

Future 模式:代表一个操作未来的结果(占位符),分两种子模式:

Promise 模式:解决回调地狱(Callback Hell)问题,将嵌套回调改写为链式调用

Skill 1:JDK Future(将来式)

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
    // 耗时操作
    return 100;
}); // 非阻塞,立即返回

// 可在此处做其他事情(并行效果)

Integer result = future.get(); // 阻塞直到结果就绪

JDK Future 接口方法:

方法 说明
get() 阻塞等待结果
get(timeout, unit) 带超时的阻塞等待
isDone() 非阻塞轮询是否完成
cancel(mayInterrupt) 取消任务
isCancelled() 是否已取消

适用场景:多个耗时操作并发执行,提交后各自 get()

Skill 2:回调式 Future(Netty)

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.22.Final</version>
</dependency>
EventExecutorGroup group = new DefaultEventExecutorGroup(4);
Future<Integer> f = group.submit(() -> {
    // 耗时操作
    return 100;
});
f.addListener(future -> {
    System.out.println("结果:" + future.get()); // 任务完成后自动触发
});
// 主线程不阻塞

Skill 3:回调式 Future(Guava ListenableFuture)

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>21.0</version>
</dependency>
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
ListenableFuture<Integer> future = service.submit(() -> {
    // 耗时操作
    return 100;
});
Futures.addCallback(future, new FutureCallback<Integer>() {
    public void onSuccess(Integer result) { /* 成功处理 */ }
    public void onFailure(Throwable t)    { /* 失败处理 */ }
});
// 主线程不阻塞

无论何时 addListener/addCallback,都能正确接收到回调,不存在错过的问题。

Skill 4:CompletableFuture(JDK 8,Promise 模式)

无需第三方依赖,解决回调地狱,支持链式调用。

基本回调:

CompletableFuture.supplyAsync(() -> {
    // 耗时操作
    return 100;
}).whenComplete((result, e) -> {
    System.out.println("结果:" + result);
});
// 主线程不阻塞

链式回调(解决回调地狱):

CompletableFuture.supplyAsync(() -> {
    // 第一步耗时操作
    return 100;
}).thenCompose(i ->
    CompletableFuture.supplyAsync(() -> {
        // 第二步耗时操作,依赖第一步结果
        return i + 100;
    })
).whenComplete((result, e) -> {
    System.out.println("最终结果:" + result); // 200
});

常用方法:

方法 说明
supplyAsync(supplier) 异步执行有返回值的任务
runAsync(runnable) 异步执行无返回值的任务
whenComplete(biConsumer) 完成后回调(含异常)
thenCompose(fn) 链式异步任务(扁平化)
thenApply(fn) 对结果做同步转换
thenAccept(consumer) 消费结果,无返回值

关系总结

Future 模式
├── 将来式:submit → get()(可能阻塞)
└── 回调式:addListener / addCallback(不阻塞)
        └── 多层嵌套 → Callback Hell
                └── Promise 模式(CompletableFuture 链式调用)解决

相关链接