这篇给你可直接复用的模板不讲大道理讲“真实项目里怎么写才稳”。先说结论在项目里写CompletableFuture最容易出问题的就三件事没有超时线程一直卡住异常没兜底主线程卡死 or 悄悄失败线程池乱用公共池被打爆解决思路有超时、有兜底、有隔离的线程池。一、基础模板统一线程池 超时 兜底ExecutorServicebizPoolnewThreadPoolExecutor(16,32,60,TimeUnit.SECONDS,newLinkedBlockingQueue(2000),newThreadFactoryBuilder().setNameFormat(biz-%d).build(),newThreadPoolExecutor.CallerRunsPolicy());CompletableFutureUserfutureCompletableFuture.supplyAsync(()-userService.getById(uid),bizPool).orTimeout(800,TimeUnit.MILLISECONDS).exceptionally(ex-{log.warn(userService fallback, uid{},uid,ex);returnUser.DEFAULT;});这个模板适合 80% 的“单个异步调用”。二、并行查询聚合allOf需求并发查用户、订单、积分CompletableFutureUserf1CompletableFuture.supplyAsync(()-getUser(uid),bizPool);CompletableFutureOrderf2CompletableFuture.supplyAsync(()-getOrder(uid),bizPool);CompletableFuturePointf3CompletableFuture.supplyAsync(()-getPoint(uid),bizPool);CompletableFutureVoidallCompletableFuture.allOf(f1,f2,f3);UserProfileprofileall.thenApply(v-{returnnewUserProfile(f1.join(),f2.join(),f3.join());}).orTimeout(1,TimeUnit.SECONDS).exceptionally(ex-UserProfile.fallback(uid)).join();注意join()会把异常包装成CompletionException一定要有兜底。三、竞速返回anyOf需求多个数据源取最快结果CompletableFutureResultf1CompletableFuture.supplyAsync(()-queryA(key),bizPool);CompletableFutureResultf2CompletableFuture.supplyAsync(()-queryB(key),bizPool);ResultresultCompletableFuture.anyOf(f1,f2).orTimeout(300,TimeUnit.MILLISECONDS).thenApply(r-(Result)r).exceptionally(ex-Result.empty()).join();四、串行依赖thenCompose需求先查用户再查用户的订单CompletableFutureOrderfutureCompletableFuture.supplyAsync(()-getUser(uid),bizPool).thenCompose(user-CompletableFuture.supplyAsync(()-getOrder(user.getId()),bizPool)).orTimeout(800,TimeUnit.MILLISECONDS).exceptionally(ex-Order.EMPTY);五、异常链处理handle vs exceptionallyCompletableFutureStringfCompletableFuture.supplyAsync(()-doWork(),bizPool).handle((res,ex)-{if(ex!null){log.warn(work failed,ex);returnfallback;}returnres;});handle能同时拿到结果和异常适合统一兜底。六、避免公共线程池被打爆不要直接用CompletableFuture.supplyAsync()默认线程池它用的是ForkJoinPool.commonPool很容易被其他任务占满。结论业务异步一定要用自定义线程池。七、一个可直接复用的“组合模板”CompletableFutureUserProfileprofileFutureCompletableFuture.supplyAsync(()-getUser(uid),bizPool).thenCombineAsync(CompletableFuture.supplyAsync(()-getOrder(uid),bizPool),(user,order)-newUserProfile(user,order),bizPool).orTimeout(800,TimeUnit.MILLISECONDS).exceptionally(ex-UserProfile.fallback(uid));最后总结写CompletableFuture最靠谱的姿势是统一线程池每段链路加超时异常统一兜底聚合前后都可回退只要把这四件事做对你的异步代码会稳很多。