Java 异步回调

🚀 Java 异步回调的两种实现方式详解

在日常开发中,我们经常会遇到这样的场景:

👉 任务提交后不阻塞主线程,任务完成后自动通知调用方

这就是典型的 异步回调模型。

本文通过一个「老板-员工」的案例,对比两种实现方式:

  • 基于 Callback 接口(传统方式)
  • 基于 CompletableFuture(推荐方式)

🧩 一、什么是异步回调?

异步回调的核心思想是:

调用方发起任务后不等待结果,而是在任务完成时由执行方主动通知调用方

📌 举个例子:

  • 老板安排任务
  • 员工执行任务(异步)
  • 员工完成后通知老板

🛠 二、基于 Callback 接口实现

1️⃣ 实现思路

流程如下:

  1. 老板调用员工执行任务
  2. 员工开启新线程处理任务
  3. 任务完成后调用回调接口通知老板

2️⃣ 核心代码

java 复制代码
interface Callback {
    void call(String result);
}
java 复制代码
class Boss implements Callback {
    Worker worker;

    public Boss(Worker worker) {
        this.worker = worker;
    }

    @Override
    public void call(String result) {
        System.out.println("【老板】收到结果:" + result);
    }

    public void makeBigDeal() {
        System.out.println("【老板】安排任务...");
        worker.execute("开发文档", this);
        System.out.println("【老板】继续做其他事情...");
    }
}
java 复制代码
class Worker {
    void execute(String work, Callback callback) {
        new Thread(() -> {
            System.out.println("【员工】开始工作:" + work);
            callback.call("code done~");
        }).start();
    }
}

3️⃣ 执行效果

复制代码
【老板】安排任务...
【老板】继续做其他事情...
【员工】开始工作:开发文档
【老板】收到结果:code done~

4️⃣ 优缺点分析

✅ 优点

  • 思想简单,容易理解
  • 贴近底层机制

❌ 缺点

  • 线程手动创建(不可控)
  • 回调嵌套容易变成"回调地狱"
  • 异常处理困难
  • 不利于复杂任务编排

⚡ 三、基于 CompletableFuture 实现(推荐)

1️⃣ 实现思路

CompletableFuture 提供了:

  • 链式调用(thenApply / thenAccept)
  • 异步执行(Async)
  • 多任务组合(allOf)

2️⃣ 核心代码

java 复制代码
@Test
void completableFutureTest() {

    // 老板下发任务
    CompletableFuture<String> workFuture =
            CompletableFuture.supplyAsync(() -> {
                System.out.println("【老板】下发任务");
                return "开发文档";
            });

    // 老板的生活
    CompletableFuture<Void> bossLife =
            CompletableFuture.runAsync(() ->
                    System.out.println("【老板】下班回家奶孩子...")
            );

    // 员工执行 + 回调
    CompletableFuture<Void> result =
            workFuture.thenApplyAsync(work -> {
                        System.out.println("【员工】执行任务:" + work);
                        return "code done~";
                    })
                    .thenAcceptAsync(res ->
                            System.out.println("【老板】收到结果:" + res)
                    );

    CompletableFuture.allOf(result, bossLife).join();
}

3️⃣ 执行流程图(逻辑)

复制代码
老板下发任务 → 员工执行 → 返回结果 → 老板收到结果
         ↓
     老板并行生活

4️⃣ 优势分析

✅ 优点

  • ✔ 链式调用,代码更优雅
  • ✔ 自动线程池(ForkJoinPool)
  • ✔ 支持任务组合(allOf / anyOf)
  • ✔ 内置异常处理(exceptionally)
  • ✔ 非阻塞编程模型

⚖️ 四、两种方式对比

对比维度 Callback CompletableFuture
编程方式 回调函数 链式调用
线程管理 手动创建 线程池
可读性 较差 高
异常处理 困难 简单
扩展性 差 强
推荐程度 ❌ ✅

💡 五、最佳实践建议

在实际项目中:

👉 不推荐:

java 复制代码
new Thread(...)

👉 推荐:

java 复制代码
CompletableFuture + 线程池

或者:

java 复制代码
ExecutorService + Future

🧠 六、总结

  • Callback 是异步回调的基础模型,本质是事件通知机制
  • CompletableFuture 是对异步编程的高级封装
  • 在现代 Java 开发中:

✅ 优先使用 CompletableFuture,而不是手写回调

相关推荐
dialect_2 小时前
KMP算法
开发语言·c++·算法
captain3762 小时前
MyBatis(入门5)其他查询操作
java·数据库·spring boot·mybatis
Novproxy_Z2 小时前
商用代理避坑:如何识别商家拿机房 IP 冒充住宅 IP
java·网络·tcp/ip
总要学点什么2 小时前
第89篇:三维特效-螺旋圆效果——让螺旋臂卷起一圈圈外扩的涟漪
开发语言·javascript·ecmascript·webgl·cesium·空间分析·1024程序员节
文丑颜不良啊3 小时前
LeetCode1481~1500题目解析
java·leetcode
2601_962885723 小时前
quotes 字段全解:涨跌幅、振幅、换手率的口径与单位
java·前端·spring
前端精髓3 小时前
调用openrouter的免费API模型
java·前端·javascript
步行cgn4 小时前
Spring MVC 拦截器 Interceptor 详解:从执行流程到实战应用
java·spring·mvc
文丑颜不良啊4 小时前
LeetCode1381~1400题目解析
java·leetcode
开开心心_Every4 小时前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea