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

异步编程——CompletableFuture用法详解

文章目录

  • 前言
  • 1. Future + 线程池
  • 2. 什么是CompletableFuture

前言

我们异步执行一个任务时,需要用线程池Executor去创建,有两种方式:

  • 如果不需要有返回值, 任务继承Thread类或实现Runnable接口;
  • 如果需要有返回值,任务实现Callable接口,调用Executorsubmit方法执行任务,再使用Future.get()获取任务结果。

当我们得到包含结果的Future时,我们可以使用get方法等待线程完成并获取返回值,但问题是Futureget()方法会阻塞主线程。并且当多个线程存在依赖组合的时候,使用同步组件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 前言 我们异步执行一个任务时&#xff0c;需要用线程池Executor去创建&#xff0c;有两种方式&#xff1a; 如果不需要有返回值&#xff0c; 任务继承Thread类或实现Runnable接口&#xff1b;如果需要有返回值&…...

Linux常用命令(不断更新)

cd 切换目录 cd .. 返回上一级目录 cd ../.. 返回上两级目录 pwd 显示工作路径 ls -l 显示文件和目录的详细信息 ls -a 列出全部文件 ls -R 连同子目录的内容一起列出 ls -lh 显示权限 cp 复制 mv 移动 rm 删除 cat 查看文件内容 find 文件搜索 文件权限 …...

C++ 浮点数二分 数的三次方根

给定一个浮点数 n &#xff0c;求它的三次方根。 输入格式 共一行&#xff0c;包含一个浮点数 n 。 输出格式 共一行&#xff0c;包含一个浮点数&#xff0c;表示问题的解。 注意&#xff0c;结果保留 6 位小数。 数据范围 −10000≤n≤10000 输入样例&#xff1a; 1000.00…...

辽宁博学优晨教育科技有限公司视频剪辑培训专业之选

随着数字时代的到来&#xff0c;视频剪辑技术已成为各行各业不可或缺的一项技能。为了满足市场需求&#xff0c;辽宁博学优晨教育科技有限公司&#xff08;以下简称“博学优晨”&#xff09;推出了专业的视频剪辑培训课程&#xff0c;旨在为广大学员提供系统、高效的学习机会。…...

数据转换成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本身写的样式&#xff0c;相当于 html&#xff0c;但优先级比后者高。 在CSS3中&#xff0c;var()函数是一个用于插入CSS自定义属性&#xff…...

武汉灰京文化展望未来游戏产业,科技创新引领全面升级的游戏体验

随着科技的迅速发展&#xff0c;未来游戏产业的发展将迎来一个全新的纪元。科技创新将引领游戏体验的全面升级&#xff0c;让玩家不再仅仅是通过屏幕与游戏互动&#xff0c;而是能够亲身感受到游戏世界的存在。这种全新的游戏体验将推动游戏产业不断突破创新&#xff0c;吸引更…...

SOLIDWORKS Visualize 界面介绍

现在有越来越多的朋友在工作中选择使用SOLIDWORKS Visualize正版软件&#xff0c;这真是太棒了!这次的主题是小索带大家了解SOLIDWORKS Visualize界面&#xff0c;让更多的朋友快速的熟悉SOLIDWORKS Visualize界面。 【菜单栏】位于界面的顶端&#xff0c;菜单栏包含多个下拉菜…...

负载均衡下webshell连接nginx解析漏洞、sql注入第一关

首先搭建环境找到php较低的版本改一下账号密码输入?id1 正常 输入?id1 报错 .0 输入?id1-- 正常 判断是字符型注入&#xff0c;闭合方式是 id是1后台看是数据表里第一行 查询id1出错前端打印出了报错信息语法错误这里是找到了库名&#xff0c;接下来是找表名这个方法是…...

养老项目技术架构和工程结构

数据层&#xff1a;MySQL、Redis 服务层&#xff1a;SpringBoot、SpringMVC、SpringCache结合Redis的缓存、定时任务XXL-JOB、和swagger配合使用生成接口文档的Knife4j、Lombok、双向通信使用的WebSocket以及Spring Security 接入层使用的nginx——反向代理、负载均衡 前端使…...

免费白嫖一个互联网创业者交流论坛,真香!

先说最重要的 当前小报童39.9&#xff0c;2.23之后会涨价到99.9 现在扫码购买&#xff0c;然后凭借截图找我全款报销&#xff0c;全款报销&#xff01; 扫码报销&#xff0c;备注“烽狂创客” 下面来看下这个专栏的内容 专栏作者是谁 挽歌&#xff0c;20岁&#xff0c;985大…...

Zilliz Cloud 再发新版本:性能提升超 10 倍,AI 应用开发流程再简化!

Zilliz Cloud 再发新版本&#xff01; 本次新版本的主要内容包括&#xff1a;大幅提升的向量搜索性能&#xff08;性能提升 10 倍以上&#xff09;、企业级数据安全和无缝数据集成。新版本发布后&#xff0c;用户无需自定义代码&#xff0c;便可快速顺畅地完成非结构化数据处理…...

基于SpringBoot的高校竞赛管理系统

基于SpringBoot的高校竞赛管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 个人中心 管理员界面 老师界面 摘要 高校竞赛管理系统是为了有效管理学校…...

【国产MCU】-CH32V307-通用定时器(GPTM)-编码模式与旋转编码器驱动

通用定时器(GPTM)-编码模式与旋转编码器驱动 文章目录 通用定时器(GPTM)-编码模式与旋转编码器驱动1、通用定时器编码模式介绍2、旋转编码器介绍3、驱动API介绍4、编码模式使用示例本文将详细介绍如何使用CH32V307通用定时器的编码模式。 1、通用定时器编码模式介绍 编码器…...

国外高防服务器需要注意哪些方面

随着互联网的快速发展&#xff0c;网络安全问题日益突出&#xff0c;高防服务器逐渐成为企业和个人用户的首选。然而&#xff0c;在选择和使用国外高防服务器时&#xff0c;需要注意以下几个方面&#xff0c;以确保安全和稳定。 一、防御能力 首先&#xff0c;需要考虑国外高防…...

MySQL系列之索引入门(下)

前言 通过上文&#xff0c;我想各位盆友已熟悉MySQL的索引分类及其含义&#xff0c;那么如何合理的使用呢&#xff1f; 请继续围观此文&#xff0c;一探究竟&#xff01; 一、创建索引 首先&#xff0c;我们一起学习索引是如何创建的&#xff0c;又有哪些方式。 1. create t…...

IO进程:fread\fwrite图像拷贝,read\write文件拷贝,时间函数

1.使用fread、fwrite实现图片拷贝 程序代码&#xff1a; 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的企业校园招聘平台的设计与实现

分享一个自己的毕业设计&#xff0c;想要获取源码的同学加V&#xff1a;qq2056908377 链接&#xff1a;https://pan.baidu.com/s/1It0CnXUvc9KVr1kDcHWvEw 提取码&#xff1a;1234 摘要&#xff1a; 摘要&#xff1a;本毕业设计旨在设计和实现一个企业校园招聘平台&#xf…...

Rocky Linux网卡静态配置

一、开源系统 Rocky Linux 下载安装 1、安装教程 Rocky Linux 下载安装 二、远程工具 MobaXterm下载安装 1、安装教程 MobaXterm 下载安装 三、Rocky Linux 网卡配置 1、使用ip addr确认网卡名称&#xff08;此处可得知网卡为ens160&#xff09; [rootlocalhost ~]# ip a 1:…...

【C语言】通讯录(静态版本+动态版本)思路解析+完整源代码

通讯录 由于代码比较长&#xff0c;为了增加可读性&#xff0c;分成了contact.h&#xff0c;contact.c&#xff0c;test.c&#xff0c;分别用来声明函数或者类型&#xff0c;实现函数功能&#xff0c;测试代码 contact.h 我们希望通讯录具有增加联系人&#xff0c;删除联系人…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

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

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

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...