异步编程——CompletableFuture用法详解
文章目录
- 前言
- 1. Future + 线程池
- 2. 什么是CompletableFuture
前言
我们异步执行一个任务时,需要用线程池Executor去创建,有两种方式:
- 如果不需要有返回值, 任务继承
Thread类或实现Runnable接口; - 如果需要有返回值,任务实现
Callable接口,调用Executor的submit方法执行任务,再使用Future.get()获取任务结果。
当我们得到包含结果的Future时,我们可以使用get方法等待线程完成并获取返回值,但问题是Future的get()方法会阻塞主线程。并且当多个线程存在依赖组合的时候,使用同步组件CountDownLatch是比较麻烦的。
Java8新增的CompletableFuture类提供了非常强大的Future的扩展功能,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了组合多个异步任务的方法。并且CompletableFuture是非阻塞性的,就是在主线程之外创建一个独立的线程,用以运行一个非阻塞的任务,然后将结果通知主线程。通过这种方式,主线程不用为了任务的完成而阻塞,极大提升了程序的性能。
1. Future + 线程池
Future是Java5引入的新接口,提供了异步并行计算的能力。如果主线程需要执行一个耗时的计算任务,我们就可以通过Future把这个任务放到异步线程中执行,主线程继续处理其他任务,处理完成后,再通过Future获取计算结果。
举个例子,假设我们有两个查询任务,一个查询运动员信息,一个查询运动员的荣誉信息。
public class PlayerInfo {private String name;private int age;}public class PlayerInfoService {public PlayerInfo getPlayerInfo() throws InterruptedException {Thread.sleep(300);//模拟调用耗时return new PlayerInfo("Kobe", 32);}}public class MedalInfo {private String medalCategory;private int medalNum;}public class MedalInfoService {public MedalInfo getMedalInfo() throws InterruptedException {Thread.sleep(500); //模拟调用耗时return new MedalInfo("MVP", 1);}}
使用Future+线程池的方式实现异步任务:
public class FutureTest {public static void main(String[] args) throws InterruptedException, ExecutionException {// 1. 创建线程池ExecutorService executorService = Executors.newFixedThreadPool(10);// 2. 任务加入线程池PlayerInfoService playerInfoService = new PlayerInfoService();MedalInfoService medalInfoService = new MedalInfoService();long startTime = System.currentTimeMillis();FutureTask<PlayerInfo> playerInfoFutureTask = new FutureTask<>(new Callable<PlayerInfo>() {@Overridepublic PlayerInfo call() throws Exception {return playerInfoService.getPlayerInfo();}});executorService.submit(playerInfoFutureTask);Thread.sleep(400);FutureTask<MedalInfo> medalInfoFutureTask = new FutureTask<>(new Callable<MedalInfo>(){@Overridepublic MedalInfo call() throws Exception {return medalInfoService.getMedalInfo();}});executorService.submit(medalInfoFutureTask);PlayerInfo playerInfo = playerInfoFutureTask.get();MedalInfo medalInfo = medalInfoFutureTask.get();System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");// 3. 关闭线程池executorService.shutdown();}}
运行结果:
总共用时905ms
如果是在主线程串行执行的话,耗时大约为300+500+400=1200ms。可见,future+线程池的异步方式,提高了程序的执行效率。但是,Future对于结果的获取,只能通过阻塞或者轮询的方式得到任务的结果。
Future.get()就是阻塞调用,在线程获取结果之前get方法会一直阻塞。阻塞的方式和异步编程的设计理念相违背。Future提供了一个isDone方法,可以在程序中轮询这个方法查询执行结果。轮询的方式会耗费CPU资源。
轮询——在计算机网络中,轮询(Polling)是一种通信方式,其中一个节点(通常是客户端)定期发送请求到另一个节点(通常是服务器)以获取数据或状态。这种方式的缺点在于,即使没有可用的数据,客户端也会持续不断地发送请求,这会消耗大量的CPU资源。此外,如果轮询的间隔设置得太短,可能会导致网络拥塞,甚至可能影响实时性。因此,轮询并不是一种高效的通信方式,特别是在需要高性能和低延迟的应用中。
2. 什么是CompletableFuture
相关文章:
异步编程——CompletableFuture用法详解
文章目录 前言1. Future 线程池2. 什么是CompletableFuture 前言 我们异步执行一个任务时,需要用线程池Executor去创建,有两种方式: 如果不需要有返回值, 任务继承Thread类或实现Runnable接口;如果需要有返回值&…...
Linux常用命令(不断更新)
cd 切换目录 cd .. 返回上一级目录 cd ../.. 返回上两级目录 pwd 显示工作路径 ls -l 显示文件和目录的详细信息 ls -a 列出全部文件 ls -R 连同子目录的内容一起列出 ls -lh 显示权限 cp 复制 mv 移动 rm 删除 cat 查看文件内容 find 文件搜索 文件权限 …...
C++ 浮点数二分 数的三次方根
给定一个浮点数 n ,求它的三次方根。 输入格式 共一行,包含一个浮点数 n 。 输出格式 共一行,包含一个浮点数,表示问题的解。 注意,结果保留 6 位小数。 数据范围 −10000≤n≤10000 输入样例: 1000.00…...
辽宁博学优晨教育科技有限公司视频剪辑培训专业之选
随着数字时代的到来,视频剪辑技术已成为各行各业不可或缺的一项技能。为了满足市场需求,辽宁博学优晨教育科技有限公司(以下简称“博学优晨”)推出了专业的视频剪辑培训课程,旨在为广大学员提供系统、高效的学习机会。…...
数据转换成json格式
// List<SpinfokuZD> xm GetmoreSpinfoku(id); // return JsonConvert.SerializeObject(xm); //将数据转换成json格式 return JsonConvert.SerializeObject(ds); //将数据转换成json格式 spcgjlZD spselld JsonConvert.Deseriali…...
css3的var()函数
css3的var()函数 变量要以两个连字符--(横杆)(减号)为开头 变量可以在:root{}中定义, :root可以在css中创建全局样式变量。通过 :root本身写的样式,相当于 html,但优先级比后者高。 在CSS3中,var()函数是一个用于插入CSS自定义属性ÿ…...
武汉灰京文化展望未来游戏产业,科技创新引领全面升级的游戏体验
随着科技的迅速发展,未来游戏产业的发展将迎来一个全新的纪元。科技创新将引领游戏体验的全面升级,让玩家不再仅仅是通过屏幕与游戏互动,而是能够亲身感受到游戏世界的存在。这种全新的游戏体验将推动游戏产业不断突破创新,吸引更…...
SOLIDWORKS Visualize 界面介绍
现在有越来越多的朋友在工作中选择使用SOLIDWORKS Visualize正版软件,这真是太棒了!这次的主题是小索带大家了解SOLIDWORKS Visualize界面,让更多的朋友快速的熟悉SOLIDWORKS Visualize界面。 【菜单栏】位于界面的顶端,菜单栏包含多个下拉菜…...
负载均衡下webshell连接nginx解析漏洞、sql注入第一关
首先搭建环境找到php较低的版本改一下账号密码输入?id1 正常 输入?id1 报错 .0 输入?id1-- 正常 判断是字符型注入,闭合方式是 id是1后台看是数据表里第一行 查询id1出错前端打印出了报错信息语法错误这里是找到了库名,接下来是找表名这个方法是…...
养老项目技术架构和工程结构
数据层:MySQL、Redis 服务层:SpringBoot、SpringMVC、SpringCache结合Redis的缓存、定时任务XXL-JOB、和swagger配合使用生成接口文档的Knife4j、Lombok、双向通信使用的WebSocket以及Spring Security 接入层使用的nginx——反向代理、负载均衡 前端使…...
免费白嫖一个互联网创业者交流论坛,真香!
先说最重要的 当前小报童39.9,2.23之后会涨价到99.9 现在扫码购买,然后凭借截图找我全款报销,全款报销! 扫码报销,备注“烽狂创客” 下面来看下这个专栏的内容 专栏作者是谁 挽歌,20岁,985大…...
Zilliz Cloud 再发新版本:性能提升超 10 倍,AI 应用开发流程再简化!
Zilliz Cloud 再发新版本! 本次新版本的主要内容包括:大幅提升的向量搜索性能(性能提升 10 倍以上)、企业级数据安全和无缝数据集成。新版本发布后,用户无需自定义代码,便可快速顺畅地完成非结构化数据处理…...
基于SpringBoot的高校竞赛管理系统
基于SpringBoot的高校竞赛管理系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringBootMyBatis工具:IDEA/Ecilpse、Navicat、Maven 系统展示 主页 个人中心 管理员界面 老师界面 摘要 高校竞赛管理系统是为了有效管理学校…...
【国产MCU】-CH32V307-通用定时器(GPTM)-编码模式与旋转编码器驱动
通用定时器(GPTM)-编码模式与旋转编码器驱动 文章目录 通用定时器(GPTM)-编码模式与旋转编码器驱动1、通用定时器编码模式介绍2、旋转编码器介绍3、驱动API介绍4、编码模式使用示例本文将详细介绍如何使用CH32V307通用定时器的编码模式。 1、通用定时器编码模式介绍 编码器…...
国外高防服务器需要注意哪些方面
随着互联网的快速发展,网络安全问题日益突出,高防服务器逐渐成为企业和个人用户的首选。然而,在选择和使用国外高防服务器时,需要注意以下几个方面,以确保安全和稳定。 一、防御能力 首先,需要考虑国外高防…...
MySQL系列之索引入门(下)
前言 通过上文,我想各位盆友已熟悉MySQL的索引分类及其含义,那么如何合理的使用呢? 请继续围观此文,一探究竟! 一、创建索引 首先,我们一起学习索引是如何创建的,又有哪些方式。 1. create t…...
IO进程:fread\fwrite图像拷贝,read\write文件拷贝,时间函数
1.使用fread、fwrite实现图片拷贝 程序代码: 1 #include<myhead.h>2 int main(int argc, const char *argv[])3 {4 //判断传入文件个数5 if(argc!3)6 {7 printf("input file error\n");8 printf("usage:./a.out …...
基于java的企业校园招聘平台的设计与实现
分享一个自己的毕业设计,想要获取源码的同学加V:qq2056908377 链接:https://pan.baidu.com/s/1It0CnXUvc9KVr1kDcHWvEw 提取码:1234 摘要: 摘要:本毕业设计旨在设计和实现一个企业校园招聘平台…...
Rocky Linux网卡静态配置
一、开源系统 Rocky Linux 下载安装 1、安装教程 Rocky Linux 下载安装 二、远程工具 MobaXterm下载安装 1、安装教程 MobaXterm 下载安装 三、Rocky Linux 网卡配置 1、使用ip addr确认网卡名称(此处可得知网卡为ens160) [rootlocalhost ~]# ip a 1:…...
【C语言】通讯录(静态版本+动态版本)思路解析+完整源代码
通讯录 由于代码比较长,为了增加可读性,分成了contact.h,contact.c,test.c,分别用来声明函数或者类型,实现函数功能,测试代码 contact.h 我们希望通讯录具有增加联系人,删除联系人…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
