点击上方“程序员蜗牛g”,选择“设为星标”跟蜗牛哥一起,每天进步一点点
程序员蜗牛g大厂程序员一枚 跟蜗牛一起 每天进步一点点31篇原创内容**公众号
今天我们就来聊聊,这个让异步编程从"青铜"变"王者"的神器!
使用场景:这些时刻请呼叫它
用法教学:从"泡面"到"米其林"
1. 基础泡面法(饿急了就用)
supplyAsync 用于开启一个异步任务并返回CompletableFuture的结果,thenApply用于处理异步任务的结果并返回一个新的CompletableFuture的结果,最后thenAccept接收处理后的结果,无返回值。
CompletableFuture.supplyAsync(() -> "煮泡面") .thenApply(noodle -> noodle + "+荷包蛋") .thenAccept(System.out::println); //输出:煮泡面+荷包蛋
例如上述代码,supplyAsync开始煮泡面,结束后thenApply拿到煮好的泡面加荷包蛋,最后thenAccept拿到煮好的泡面+荷包蛋开吃。
2. 高阶米其林套餐(装X必备)
thenCombine 用于组合两个独立的CompletableFuture的结果,当两者都完成时,用指定的函数合并结果,返回一个新的CompletableFuture。
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> "抓一只波士顿龙虾");
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> "准备82年的白葡萄酒");
task1.thenCombine(task2, (lobster, wine) -> "烹饪" + lobster + "佐以" + wine) .exceptionally(ex -> "菜糊了?没事,点外卖!") //优雅降级 .thenAccept(chef::serve);
例如上述代码task1:抓一只波士顿龙虾和task2:准备82年的白葡萄酒互不影响,当两个任务都完成后使用thenCombine合并两个任务的结果完成后续操作,exceptionally用于处理突发情况(处理异常),thenAccept最后完成菜品。
3. 神级操作(同事看懵系列)
假设有三个任务,任务1、2、3互相不影响,如下supplyAsync开启三个任务,然后通过allOf方法等待所有任务执行完毕,最后thenRun拿到所有任务结果。
List<CompletableFuture<String>> futures = Arrays.asList( CompletableFuture.supplyAsync(() -> "查询1月份报表"), CompletableFuture.supplyAsync(() -> "查询2月份报表"), CompletableFuture.supplyAsync(() -> "查询3月份报表"));
//等所有任务执行完CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));allFutures.thenRun(() -> { futures.forEach(f -> System.out.println(f.join()));// 收集所有结果}).join();// 输出:查询1月份报表// 查询2月份报表// 查询3月份报表
四、最佳实践:别让你的代码"翻车"
1. 线程池不是垃圾桶
❌ 错误姿势:无脑用默认的ForkJoinPool,迟早OOM警告!
✅ 正确姿势:自定义线程池,像控制奶茶糖分一样精准!
在Java中,ForkJoinPool.commonPool()是CompletableFuture默认使用的线程池,但在高并发、阻塞型任务或复杂业务场景中,直接依赖默认线程池可能引发性能问题。下次详细聊聊。
2. 异常处理是安全带
- 用
exceptionally()给代码买保险 - 用
handle()统一处理成功/失败
(不然线上报错时,你会像没保存PS的甲方需求一样崩溃)
3. 拒绝"套娃"代码
- 超过3层的
thenApply()建议拆方法 - 组合复杂逻辑用
thenCompose()扁平化
(否则调试时,你会感觉在看盗梦空间第5层)
如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。
关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!