CompletableFuture学习整理

简介: 整理的原因是在Sentinel源码中,我们可以看到很多关于CompletableFuture的thenCompose的源码。同时在业务系统里面也看到别人写过类似的代码。因此整理了一下关于CompletableFuture使用的相关类型和特性,在处理复杂耗时业务时可以选择组合使用。

一、整理的原因

整理的原因是在Sentinel源码中,我们可以看到很多关于CompletableFuture的thenCompose的源码。同时在业务系统里面也看到别人写过类似的代码。其中Sentinel一处代码如下:

privatevoidapplyAllClientConfigChange(Stringapp, ClusterAppAssignMapassignMap,

                                           Set<String>failedSet) {

       Set<String>clientSet=assignMap.getClientSet();

       if (clientSet==null||clientSet.isEmpty()) {

           return;

       }

       finalStringserverIp=assignMap.getIp();

       finalintserverPort=assignMap.getPort();

       clientSet.stream()

           .map(MachineUtils::parseCommandIpAndPort)

           .filter(Optional::isPresent)

           .map(Optional::get)

           .map(ipPort-> {

               CompletableFuture<Void>f=sentinelApiClient

                   .modifyClusterMode(ipPort.r1, ipPort.r2, ClusterStateManager.CLUSTER_CLIENT)

                   .thenCompose(v->sentinelApiClient.modifyClusterClientConfig(app, ipPort.r1, ipPort.r2,

                       newClusterClientConfig().setRequestTimeout(20)

                           .setServerHost(serverIp)

                           .setServerPort(serverPort)

                   ));

               returnTuple2.of(ipPort.r1+'@'+ipPort.r2, f);

           })

           .forEach(t->handleFutureSync(t, failedSet));

   }

因此整理了一下关于CompletableFuture使用的相关类型和特性,在处理复杂耗时业务时可以选择组合使用。

下面相关方法的demo参考我的github上的demo:

https://github.com/123monkey/practice.git

二、相关的使用方法

1.supplyAsync

有返回值

2.runAsync

不支持返回值

3.completableFuture获取结果

join:抛出的是uncheck异常(即未经检查的异常),不会强制开发者抛出

get:抛出的是受查异常,ExecutionException, InterruptedException 需要用户手动处理(抛出或者 try catch)

4.计算结果完成后的处理方法

whenComplete
  • 当completableFuture的计算结果完成,或者抛异常时,可以执行特定的action
whenCompleteAsync
  • 把whenCompleteAsync的任务action继续提交给线程池来执行,即执行CompletableFuture的任务和执行whenCompleteAsync的任务的线程可能是两个不同的线程
thenApply
  • 当线程B依赖于线程A的执行结果时,可以使用thenApply方法来把这两个线程串行化
thenApplyAsync
  • 线程异步
handle
  • handle方法和thenApply方法处理方式基本一样,不同的是handle里的方法是在supplyAsync/runAsync执行后一定会执行的,即使supplyAsync/runAsync里抛了异常也会执行handle里的方法,而thenApply只可以执行正常的任务,任务出现异常则不执行thenApply方法
handleAsync
  • 处理线程异步
thenAccept
  • thenAccept方法同样也是对前面的supplyAsync/runAsync生成的结果进行消费,但是不同点在于thenAccept方法只是纯消费,不返回值
thenCompose
  • thenCompose()用来连接两个CompletableFuture,返回值是新的CompletableFuture;
  • thenApply()转换的是泛型中的类型,是同一个CompletableFuture。
thenCombine
  • thenCombine会把两个CompletableFuture的任务都执行完成后,把两个任务的结果一块交给thenCombine来处理,并生成新的CompletableFuture任务。

5.allOf

allOf方法的入参是若干个CompletableFuture任务,返回类型是CompletableFuture,allOf方法是等所有的CompletableFuture都执行完后再执行计算,一般后面会跟链式的thenApply方法或者thenAccept方法对所有的异步任务进行汇总处理

6.anyOf

anyOf方法入参是若干个CompletableFuture任务,返回类型是CompletableFuture,anyOf方法只要有一个CompletableFuture任务完后就执行计算,一般后面会跟链式的thenApply方法或者thenAccept方法对结果进行处理,anyOf方法没allOf方法使用广泛。

三、整理的xmind

image-20230216222859450.png


目录
相关文章
|
6月前
|
存储 关系型数据库 PostgreSQL
在 RDS PostgreSQL 中实现 RaBitQ 量化
本文介绍阿里云RDS PostgreSQL中pgvector的RaBitQ向量量化技术:通过1-bit二值压缩实现32倍索引空间缩减,显著提升千万级向量场景下的存储效率与查询性能,同时保障高召回率,无需引入专用向量数据库。
在 RDS PostgreSQL 中实现 RaBitQ 量化
|
SQL 存储 关系型数据库
什么是MySQL Workbench
【10月更文挑战第17天】什么是MySQL Workbench
2063 0
|
Java 数据库连接 API
2025 更新必看:Java 编程基础入门级超级完整版指南
本教程为2025更新版Java编程基础入门指南,涵盖开发环境搭建(SDKMAN!管理JDK、VS Code配置)、Java 17+新特性(文本块、Switch表达式增强、Record类)、面向对象编程(接口默认方法、抽象类与模板方法)、集合框架深度应用(Stream API高级操作、并发集合)、模式匹配与密封类等。还包括学生成绩管理系统实战项目,涉及Maven构建、Lombok简化代码、JDBC数据库操作及JavaFX界面开发。同时提供JUnit测试、日志框架使用技巧及进阶学习资源推荐,助你掌握Java核心技术并迈向高级开发。
1133 5
|
数据可视化 数据挖掘 数据处理
Pandas高级数据处理:窗口函数
Pandas 是 Python 中强大的数据分析库,窗口函数(如 `rolling`、`expanding` 和 `ewm`)用于滚动计算、累积计算等。本文介绍窗口函数的基本概念、代码示例及常见问题解决方法,帮助读者灵活运用这些工具进行数据分析。通过合理选择窗口大小、处理边界值和缺失数据,以及优化性能,充分发挥窗口函数的优势。
711 27
|
存储 NoSQL 关系型数据库
什么是 CAP 理论和 BASE 理论,看这一篇就够了
什么是 CAP 理论和 BASE 理论,看这一篇就够了
1457 13
|
机器学习/深度学习 监控 项目管理
『软件工程4』一文了解软件项目管理中的4P
该文章讲述了软件项目管理中的四个关键要素(4P:People、Product、Process、Project)的重要性及如何在实践中应用这些要素来提高项目管理的有效性。
『软件工程4』一文了解软件项目管理中的4P
|
JavaScript
vue 一键复制vue-clipboard2
vue 一键复制vue-clipboard2
330 0
|
缓存 JavaScript 前端开发
Vue 3的事件监听缓存如何优化性能?
【10月更文挑战第5天】随着前端应用复杂度的增加,性能优化变得至关重要。Vue 3 通过引入事件监听缓存等新特性提升了应用性能。本文通过具体示例介绍这一特性,解释其工作原理及如何利用它优化性能。与 Vue 2 相比,Vue 3 可在首次渲染时注册事件监听器并在后续渲染时重用,避免重复注册导致的资源浪费和潜在内存泄漏问题。通过使用 `watchEffect` 或 `watch` 监听状态变化并更新监听器,进一步提升应用性能。事件监听缓存有助于减少浏览器负担,特别在大型应用中效果显著,使应用更加流畅和响应迅速。
739 1
|
监控 NoSQL Redis
开发者如何使用阿里云Redis
【10月更文挑战第2天】开发者如何使用阿里云Redis
2315 0