当前位置: 首页 > news >正文

CompletableFuture 详解

目录

简单介绍

常见操作

创建 CompletableFuture

new 关键字

静态工厂方法

处理异步结算的结果


简单介绍

CompletableFuture 同时实现了 Future 和 CompletionStage 接口。

public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
}

 CompletableFuture 除了提供了更为好用和强大的 Future 特性之外,还提供了函数式编程的能力。

Future 接口有 5 个方法:

  • boolean cancel(boolean mayInterruptIfRunning):尝试取消执行任务。
  • boolean isCancelled():判断任务是否被取消。
  • boolean isDone():判断任务是否已经被执行完成。
  • get():等待任务执行完成并获取运算结果。
  • get(long timeout, TimeUnit unit):多了一个超时时间。

CompletionStage 接口描述了一个异步计算的阶段。很多计算可以分成多个阶段或步骤,此时可以通过它将所有步骤组合起来,形成异步计算的流水线。

CompletionStage 接口中的方法比较多,CompletableFuture 的函数式能力就是这个接口赋予的。从这个接口的方法参数你就可以发现其大量使用了 Java8 引入的函数式编程。

常见操作

 

创建 CompletableFuture

常见的创建 CompletableFuture 对象的方法如下:

  1. 通过 new 关键字。
  2. 基于 CompletableFuture 自带的静态工厂方法:runAsync()supplyAsync()

new 关键字

通过 new 关键字创建 CompletableFuture 对象这种使用方式可以看作是将 CompletableFuture 当做 Future 来使用。

下面咱们来看一个简单的案例。

我们通过创建了一个结果值类型为 RpcResponse<Object>CompletableFuture,你可以把 resultFuture 看作是异步运算结果的载体。

CompletableFuture<RpcResponse<Object>> resultFuture = new CompletableFuture<>();

假设在未来的某个时刻,我们得到了最终的结果。这时,我们可以调用 complete() 方法为其传入结果,这表示 resultFuture 已经被完成了。

// complete() 方法只能调用一次,后续调用将被忽略。
resultFuture.complete(rpcResponse);

你可以通过 isDone() 方法来检查是否已经完成。

public boolean isDone() {return result != null;
}

获取异步计算的结果也非常简单,直接调用 get() 方法即可。调用 get() 方法的线程会阻塞直到 CompletableFuture 完成运算。

rpcResponse = completableFuture.get();

如果你已经知道计算的结果的话,可以使用静态方法 completedFuture() 来创建 CompletableFuture 。

CompletableFuture<String> future = CompletableFuture.completedFuture("hello!");
assertEquals("hello!", future.get());

completedFuture() 方法底层调用的是带参数的 new 方法,只不过,这个方法不对外暴露。

public static <U> CompletableFuture<U> completedFuture(U value) {return new CompletableFuture<U>((value == null) ? NIL : value);
}

静态工厂方法

这两个方法可以帮助我们封装计算逻辑。

static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier);
// 使用自定义线程池(推荐)
static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor);
static CompletableFuture<Void> runAsync(Runnable runnable);
// 使用自定义线程池(推荐)
static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor);

runAsync() 方法接受的参数是 Runnable ,这是一个函数式接口,不允许返回值。当你需要异步操作且不关心返回结果的时候可以使用 runAsync() 方法。

@FunctionalInterface
public interface Runnable {public abstract void run();
}

supplyAsync() 方法接受的参数是 Supplier<U> ,这也是一个函数式接口,U 是返回结果值的类型。

@FunctionalInterface
public interface Supplier<T> {/*** Gets a result.** @return a result*/T get();
}

当你需要异步操作且关心返回结果的时候,可以使用 supplyAsync() 方法。

CompletableFuture<Void> future = CompletableFuture.runAsync(() -> System.out.println("hello!"));
future.get();// 输出 "hello!"
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "hello!");
assertEquals("hello!", future2.get());

处理异步结算的结果

当我们获取到异步计算的结果之后,还可以对其进行进一步的处理,比较常用的方法有下面几个:

  • thenApply()
  • thenAccept()
  • thenRun()
  • whenComplete()

thenApply() 方法接受一个 Function 实例,用它来处理结果。

// 沿用上一个任务的线程池
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) {return uniApplyStage(null, fn);
}//使用默认的 ForkJoinPool 线程池(不推荐)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn) {return uniApplyStage(defaultExecutor(), fn);
}
// 使用自定义线程池(推荐)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor) {return uniApplyStage(screenExecutor(executor), fn);
}

如果你不需要从回调函数中获取返回结果,可以使用 thenAccept() 或者 thenRun()。这两个方法的区别在于 thenRun() 不能访问异步计算的结果。

thenAccept() 方法的参数是 Consumer<? super T> 。

public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {return uniAcceptStage(null, action);
}public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) {return uniAcceptStage(defaultExecutor(), action);
}public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor) {return uniAcceptStage(screenExecutor(executor), action);
}

相关文章:

CompletableFuture 详解

目录 简单介绍 常见操作 创建 CompletableFuture new 关键字 静态工厂方法 处理异步结算的结果 简单介绍 CompletableFuture 同时实现了 Future 和 CompletionStage 接口。 public class CompletableFuture<T> implements Future<T>, CompletionStage<T…...

el-table数据处理

在写表格时遇到&#xff0c;后端返回的数据是对象&#xff0c;并且缺少字段 1.每一条数据加上 一个字段 2.将对象转成数组 以下是数据 {"groupA": {"groupName": null,"orgName": null,"orgId": null,"allPeoper": &quo…...

IPv4网络用户访问IPv6网络服务器

NAT64静态映射为一对一的对应关系&#xff0c;通常应用在IPv4网络主动访问IPv6网络的场景中。 要求位于IPv4网络中的PC通过IPv4地址1.1.1.10能够直接访问位于IPv6网络中Server。 操作步骤 配置FW。 # 配置接口GigabitEthernet 0/0/1的IPv4地址。 <FW> system-view [F…...

程序员是怎么记住代码的?

程序员能记住所有东西吗&#xff1f; 程序员不会记住他们使用的所有代码&#xff0c;相反&#xff0c;他们倾向于阅读文档&#xff0c;学习基本概念&#xff0c;并使用软件社区来解决问题。大约55%的软件开发人员报告每天至少使用一次StackOverflow来帮助解决编程问题。 使用…...

华为云NFS使用API删除大文件目录

最近在使用华为云SFS时&#xff0c;如果一个目录存储文件数超过100W&#xff0c;执行 “rm -rf path”时&#xff0c;存在删不动的情况&#xff0c;可以使用华为云API接口&#xff0c;执行异步删除。 华为官网&#xff1a; 删除文件系统目录_弹性文件服务 SFS_API参考_SFS Tu…...

国家金融监督管理总局明确将数据安全管理纳入操作风险管理范畴

为进一步完善银行保险机构操作风险监管规则&#xff0c;提升银行保险机构的操作风险管理水平&#xff0c;国家金融监督管理总局起草了《银行保险机构操作风险管理办法&#xff08;征求意见稿&#xff09;》&#xff08;以下简称《办法》&#xff09;&#xff0c;现向社会公开征…...

.asScala爆红

转载&#xff1a;asScala报错 解决方案&#xff1a; 导入隐式转换 import scala.collection.JavaConverters._ //asScala需要使用隐式转换 代码中的asScala就可能不标红了&#xff0c;如果标红&#xff0c;就直接去掉&#xff0c;去掉就不报错了...

SOLIDWORKS Utilities应用

在实际的生产设计制造中&#xff0c;经常会遇到同一个零件多个版本&#xff0c;有可能再次调用零件的时间已经是很长时间之后&#xff0c;对于版本之间的区别就不会那么清楚&#xff0c;碰到简单明显的零件还可以轻松的找到区别&#xff0c;但是复杂的零件区别的查找可能会造成…...

发现的宝藏开源软件

1.华夏erp https://github.com/jishenghua/jshERP 2.s2b2c商城 后端 lilishop商城 电商 java商城系统: lilishop商城基于SpringBoot 全端开源 电商商城系统 支持小程序商城 H5商城 APP商城 PC商城 。支持业务模式包含 O2O商城 B2B商城 多语言商城 跨境电商 B2B2C商城 F2B2C商…...

【八】mybatis 日志模块设计

mybatis 日志模块设计 简介&#xff1a;闲来无事阅读一下mybatis的日志模块设计&#xff0c;学习一下优秀开源框架的设计思路&#xff0c;提升自己的编码能力 模块设计 在Mybatis内部定义了4个级别&#xff1a;Error:错误 、warn:警告、debug:调试、trance&#xff0c;日志优…...

Python-如何使用正则表达式

如何利用Python使用正则表达式 目录 正则表达式常用匹配规则 ​编辑re库的使用 match()方法&#xff1a; search()方法: findall()方法 : sub()方法: compile()方法; 通用匹配 贪婪与非贪婪匹配 贪婪匹配 非贪婪匹配 修饰符 转义匹配 正则表达式是处理字符的强大…...

分解质因子,将一个不小于2的整数分解质因数,例如,输入90,则输出:90=2*3*3*5

假设一个不小于2的整数n&#xff0c;对从2开始的自然数k&#xff0c;这个试探它是否是整数n的一个因子&#xff0c;如果是&#xff0c;则输出该因子&#xff0c;并将n/k的结果赋给n&#xff08;接下来只需要对n除以已经找到的因子之后的结果继续找因子&#xff09;。如果n的值不…...

C语言,vs各种报错分析(不断更新)

1.引发了异常: 写入访问权限冲突2.#error: Error in C Standard Library usage 1.引发了异常: 写入访问权限冲突 这里是malloc没有包含头文件<stdlib.h>&#xff0c;包含之后就好了 2.#error: Error in C Standard Library usage 这里就是用C语言写程序时使用了C的头文件…...

AR开发平台 | 探索AR技术在建筑设计中的创新应用与挑战

随着AR技术的不断发展和普及&#xff0c;越来越多的建筑师开始探索AR技术在建筑设计中的应用。AR(增强现实)技术可以通过将虚拟信息叠加到现实场景中&#xff0c;为设计师提供更加直观、真实的建筑可视化效果&#xff0c;同时也可以为用户带来更加沉浸式的体验。 AR开发平台广…...

小白到运维工程师自学之路 第六十集 (docker的概述与安装)

一、概述 1、客户&#xff08;老板&#xff09;-产品-开发-测试-运维项目周期不断延后&#xff0c;项目质量差。 随着云计算和DevOps生态圈的蓬勃发展&#xff0c;产生了大量优秀的系统和软件。软件开发人员可以自由选择各种软件应用环境。但同时带来的问题就是需要维护一个非…...

SpringBoot 集成 Elasticsearch

一、版本 spring-boot版本&#xff1a;2.3.7.RELEASEElasticsearch7.8.0版本说明详见 二、Elasticsearch 下载和安装 Elasticsearch 下载 kibana下载 ik分词器下载 配置IK分词器 2.1 解压&#xff0c;在elasticsearch-7.8.0\plugins 路径下新建ik目录 2.2 将ik分词器解压放…...

【ES】使用日志记录

1、修改操作 1、要删除Elasticsearch索引的分区下的数据 <index_name>是要删除数据的索引名称。这个命令会删除该索引下的所有数据。 POST /<index_name>/_delete_by_query {"query": {"match_all": {}} }2、删除特定条件下的数据 要删除a…...

svn还原本地代码

svn代码还原 问题描述&#xff1a;在vscode中修改了代码&#xff0c;没有提交&#xff0c;而且不小心点击了svn更新&#xff0c;导致本地修改的最新代码被覆盖&#xff0c;因为没有提交&#xff0c;所以远程仓库中也没有刚才修改的代码记录 解决&#xff1a; 通过vscode的时间…...

zore-shot,迁移学习和多模态学习

1.zero-shot 定义&#xff1a;在ZSL中&#xff0c;某一类别在训练样本中未出现&#xff0c;但是我们知道这个类别的特征&#xff0c;然后通过语料知识库&#xff0c;便可以将这个类别识别出来。概括来说&#xff0c;就是已知描述&#xff0c;对未知类别&#xff08;未在训练集中…...

【Golang 接口自动化07】struct转map的三种方式

目录 背景 struct转map 使用json模块 使用reflect模块 使用第三方库 测试 总结 资料获取方法 背景 我们在前面介绍过怎么使用net/http发送json或者map数据&#xff0c;那么它能不能直接发送结构体数据呢&#xff1f;我们今天一起来学习结构体struct转map的三种方法&am…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...