我把 CompletableFuture 踩坑经验写成了 AI Skill,比自己写代码还靠谱

35 阅读3分钟

写了五年 Java,团队快把CompletableFuture 的坑踩了个遍。

在 Stream 里 join(),以为并行其实串行。用 thenApply 没加 Async,回调跑到 Delayer 线程上把全局调度卡死。嵌套 join() 导致线程池死锁,排查了三天。allOf 以为是 fail-fast,傻等所有任务超时才返回。很多踩坑和避坑都是线上事故换来的。半夜 oncall,周末加班 debug。

后来我把这些写成博客,20 多篇,总结了 8 个常见陷阱。那篇《CompletableFuture 超时功能有大坑》阅读量 6000+。但说实话,90% 的读者下次写代码还是会犯同样的错。不是不想记,是记不住。然后我想,这些规则 AI 能记住。

博客的问题

传统路径是这样:踩坑,总结,写博客,读者看,读者记,读者用。

链路太长了。人会忘,AI 不会。

我试着把这些规则写成 Skill。现在的路径变成:踩坑,总结,写 Skill,AI 实时检查,问题直接拦截。

知识不用记了,自动执行。

这个 Skill 干什么

三种模式。

Code Review:你写完代码,它逐项检查。迭代中 join(串行执行),嵌套 join(死锁风险),不带 Async(阻塞调度线程),同步异常逃逸,allOf 非快速失败,超时不取消,异常被吞,默认线程池。八个坑,按严重程度分类。

实现指导:你说需求,它直接给代码。比如"并发查询多个用户,任一失败立即返回":

List<CompletableFuture<User>> cfs = userIds.stream()
    .map(id -> CompletableFuture.supplyAsync(
        () -> userService.getById(id), executor))
    .toList();

// CfIterableUtils 来自 CFFU 库:https://github.com/foldright/cffu
List<User> users = CfIterableUtils.allResultsFailFastOf(cfs)
    .orTimeout(3, TimeUnit.SECONDS)
    .exceptionallyAsync(ex -> {
        log.error("批量查询失败", ex);
        throw new BusinessException("查询失败", ex);
    }, executor)
    .join();

显式执行器,快速失败,超时控制,Async 后缀,全带上了。

问题诊断:"线程池满了",检查嵌套 join。"任务超时还在跑",解释 orTimeout 不取消任务。"exceptionally 没捕获异常",查同步异常逃逸。

对比一下

普通开发写的:

public List<Result> queryAll(List<String> ids) {
    return ids.stream()
        .map(id -> CompletableFuture.supplyAsync(() -> query(id)))
        .map(cf -> cf.join())
        .toList();
}

看着像并发,跑起来是串行。没超时控制,可能无限阻塞。没异常处理,炸了直接抛。用默认线程池,跟别的任务抢资源。

Skill 指导后:

public List<Result> queryAll(List<String> ids) {
    CompletableFuture<?>[] cfs = ids.stream()
        .map(id -> CompletableFuture.supplyAsync(
            () -> query(id), businessExecutor))
        .toArray(CompletableFuture[]::new);

    // CFFU 提供快速失败语义,原生 allOf 会等所有任务完成
    return CfIterableUtils.allResultsFailFastOf(cfs)
        .orTimeout(3, TimeUnit.SECONDS)
        .exceptionallyAsync(ex -> {
            log.error("批量查询失败", ex);
            return Collections.emptyList();
        }, businessExecutor)
        .join();
}

代码量差不多,但一个能上线一个不能。

当前工作流

踩坑,写博客沉淀思考,提取规则,写成 Skill,项目里验证,迭代优化。这个 Skill 就是这么来的。20 多篇博客变成 8 条陷阱清单,6 条最佳实践变成 Checklist,无数次 oncall 变成诊断流程。

工程师的角色在变

以前写代码,现在写约束。以前培训新人,现在训练 AI。以前 Code Review 人工看,现在自动检查。以前经验在脑子里,现在经验在 Skill 里。这个 completablefuture-optimizer 就是个例子。它是约束,让 AI 只能输出符合最佳实践的代码。它是知识库,包含所有已知陷阱。它是自动化 Code Review。

以后可能每个资深开发都有自己的 Skill 库。DBA 有 SQL 优化的,架构师有设计模式的,SRE 有故障排查的。经验不再是只能靠带新人传递的东西,可以直接让 AI 执行。


Skill 获取good-skills/completablefuture-optimizer

使用方式:把 Skill 放到 ~/.claude/skills/completablefuture-optimizer/SKILL.md,然后跟 Claude 说"review 这段异步代码"或者"帮我实现并发查询"。

CFFU 库github.com/foldright/c…