异步编程——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 我们希望通讯录具有增加联系人,删除联系人…...
OpenClaw调试技巧:千问3.5-9B接口调用问题排查
OpenClaw调试技巧:千问3.5-9B接口调用问题排查 1. 为什么需要关注接口调用问题 上周我在本地部署OpenClaw对接千问3.5-9B模型时,遇到了一个诡异的问题:明明配置文件正确,模型服务也正常运行,但OpenClaw就是无法完成对…...
XBee API模式通信原理与嵌入式集成实战
1. XBee 库技术解析:面向嵌入式系统的 API 模式通信框架XBee 是 Digi International 推出的一系列低功耗、高可靠性的无线射频模块,广泛应用于工业物联网、远程传感器网络、智能农业及楼宇自动化等场景。其核心优势在于支持多种协议栈(Zigbee…...
现代Qt开发——入门 · 环境搭建 · 00 · Qt6 安装踩坑指南
现代Qt开发——入门 环境搭建 00 Qt6 安装踩坑指南 相关仓库仍然已经开源,正在积极火热的建设之中,欢迎各位大佬提Issue和PR! 链接地址:https://github.com/Awesome-Embedded-Learning-Studio/Tutorial_AwesomeQt 1. 前言&…...
RetDec反编译神器:从零开始掌握二进制代码逆向分析
RetDec反编译神器:从零开始掌握二进制代码逆向分析 【免费下载链接】retdec RetDec is a retargetable machine-code decompiler based on LLVM. 项目地址: https://gitcode.com/gh_mirrors/re/retdec 你是否曾经面对一个神秘的二进制文件,想要了…...
经典入门教程:Simulink二次调频AGC系统解析,含储能与火电机组应用
simulink二次调频AGC,含储能、火电机组。 经典两区域系统二次调频,适合初学者入门。电力系统二次调频就像给电网做瑜伽——既要保持平衡,又要灵活应对突发状况。今天咱们用Simulink撸个带储能的两区域AGC模型,手把手感受火力发电机…...
【12.MyBatis源码剖析与架构实战】9.1 ⼆级缓存的原理
二级缓存(L2 Cache)是计算机体系结构中的关键组件,位于一级缓存(L1)和主内存之间,用于弥合CPU与内存之间的速度差异。下面详细解析其原理,并配合流程图说明数据访问流程。 一、二级缓存的核心原理 1. 存储层次定位 L1缓存:极快(~1ns),极小(32-64KB),与CPU核心紧…...
考虑需求响应和碳交易的综合能源系统日前优化调度模型 关键词:柔性负荷 需求响应 综合能源系统 ...
考虑需求响应和碳交易的综合能源系统日前优化调度模型 关键词:柔性负荷 需求响应 综合能源系统 参考:私我 仿真平台:MATLAB yalmipcplex 主要内容:在冷热电综合能源系统的基础上,创新性的对用户侧资源进行了细致的划…...
《SpaceOS:空间操作系统白皮书(终极封神版)》——从“像素认知”到“空间计算”,构建现实世界的智能操作体系
🚀《SpaceOS:空间操作系统白皮书(终极封神版)》——从“像素认知”到“空间计算”,构建现实世界的智能操作体系(镜像视界(浙江)科技有限公司原创技术体系)🔴 …...
告别DCOM噩梦:手把手教你用KepOPC DA2UA中间件搞定OPC DA到UA的转换(附Python读写测试代码)
工业数据互通新范式:零配置实现OPC DA到UA的无缝迁移实战 如果你是一名工业自动化工程师,一定对这样的场景不陌生:凌晨两点还在客户现场调试DCOM配置,反复检查防火墙规则、用户权限和网络策略,却依然无法让OPC DA客户端…...
如何利用WebSocket实现biliup的实时直播状态监控与日志推送:完整指南
如何利用WebSocket实现biliup的实时直播状态监控与日志推送:完整指南 【免费下载链接】biliup 自动直播录制、投稿、twitch、ytb频道搬运工具。命令行投稿(B站)和视频下载工具,提供多种登录方式,支持多p。 项目地址: https://gitcode.com/g…...
