java多线程编码应用1——java多线程CompletableFuture使用技巧

在实际项目开发过程中,大部分程序的执行顺序都是按照代码编写的先后顺序,依次从上往下挨个执行的,但是对于统计或者批量操作数据时,是否有更好的方案呢?这时候就可以考虑使用多线程编程,异步并行执行多个任务,从而提升用户使用体验,发挥多核cpu的性能。

更多关于CompletableFuture的说明,请参看如下文章:

Java多线程之CompletableFuture_java completablefuture-CSDN博客

Java中的CompletableFuture原理与用法_java_脚本之家

以下文案是基于数据统计方案去设计编写的,希望可以对各位有所帮助。

一.CompletableFuture是什么

CompletableFuture是由Java8引入的,用于异步编程,异步通常意味着非阻塞,运行任务单独的线程,与主线程隔离。并且通过回调可以在主线程中得到异步任务的执行状态,是否完成和异常等信息。通过这种方式编程主线程不会被阻塞,不需要等到多个子线程执行完成,它可以并行执行其他任务。使用这种并行编程方式,可以极大的提高程序的执行和运行效率,提升用户使用体验等。

与Future对比:

  • CompletableFuture默认使用的是ForkJoinPool线程池;
  • CompletableFuture 是 Future API的扩展;
  • Future在实际使用过程中存在局限性,如不支持异步任务的编排组合,获取计算结果的get() 方法为阻塞调用;
  • CompletableFuture除了提供了更为好用和强大的 Future 特性之外,还提供了函数式编程、异步任务编排组合等扩展功能。

 二.如何创建CompletableFuture实例

1. supplyAsync()

通过该函数创建的CompletableFuture实例会异步执行当前传入的计算任务。在调用端,则可以通过get或join获取最终计算结果。

/**
* 有返回值的
* 如果不指定线程池,默认的构造方法使用ForkJoinPool
**/
ExecutorService executorService = Executors.newFixedThreadPool(4);
CompletableFuture<List<SysDept>> cfDeptList= CompletableFuture.supplyAsync(() -> {return remoteStationService.getAllStationInfo(0).getData();},executorService);
List<SysDept> join = cfDeptList.join();
2.runAsync()

与supplyAsync()不同的是,runAsync()传入的任务要求是Runnable类型的,所以没有返回值。因此,runAsync适合创建不需要返回值的计算任务。

//无返回值
CompletableFuture cf = CompletableFuture.runAsync(()->{getFireFightingData(params,resultAll);},fjp);
3.Future.get()和CompletableFuture.join()对比
  • 这两个方法都是阻塞方法,用于获取异步任务的结果。
  • Future.get()方法在获取异步任务结果时更具灵活性,因为它必须声明抛出异常且需要手动处理,同时它会阻塞线程调用。
  • CompletableFuture.join() 方法更适用于使用 ForkJoinPool 线程池执行任务的情况,它更方便用于不会阻塞 ForkJoinPool 线程池中的线程中。

三.CompletableFuture使用

        //仅展示部分关键代码        ForkJoinPool fjp = new ForkJoinPool(8);System.out.println("默认使用的线程为:" + Thread.currentThread().getName());CompletableFuture cf1 = CompletableFuture.runAsync(()->{System.out.println("cf1使用的线程为:" + Thread.currentThread().getName());//站数据List<StationDTO> stationAllVoList = staMapper.getAllStationVoList(null);Map<String, StationDTO> stationAllVoMap = null;if(CollectionUtils.isNotEmpty(stationAllVoList)){stationAllVoMap = stationAllVoList.stream().collect(Collectors.toMap(StationDTO::getStationName, Function.identity()));}else {stationAllVoMap = new HashMap<>();}resultAll.put("stationAllVoMap",stationAllVoMap);},fjp);System.out.println("cf1使用完之后的线程为:" + Thread.currentThread().getName());CompletableFuture cf2 = CompletableFuture.runAsync(()->{System.out.println("cf2使用的线程为:" + Thread.currentThread().getName());getSafetyCountData(params,resultAll);},fjp);CompletableFuture cf3 = CompletableFuture.runAsync(()->{System.out.println("cf3使用的线程为:" + Thread.currentThread().getName());getRectifyRateData(params,resultAll);},fjp);CompletableFuture cf4 = CompletableFuture.runAsync(()->{System.out.println("cf3使用的线程为:" + Thread.currentThread().getName());getAlarmARemindData(params,resultAll);},fjp);CompletableFuture.allOf(cf1,cf2,cf3,cf4).join();fjp.shutdown();

需要注意的点:

  • allOf()返回的CompletableFuture是多个任务都执行完成后才会执行,只要有一个任务执行异常,则返回的CompletableFuture执行get方法时会抛出异常,如果都是正常执行,则get返回null。
  • anyOf()返回的CompletableFuture是多个任务只要其中一个执行完成就会执行,其get返回的是已经执行完成的任务的执行结果,如果该任务执行异常,则抛出异常。

四. 模拟测试验证

经过测试, 多个子线程执行并不会影响主线程的继续执行,也不存在线程阻塞问题,与设计效果保持一致,非常值得借鉴学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/833881.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嘉楠堪智 CanMV K230 进行 C 语言程序开发

本文记录学习、使用 K230 SDK 进行 C 语言程序开发的一些关键步骤&#xff0c;编写程序源代码&#xff0c;如何编译运行在大核和小核的程序&#xff0c;如何使用 SCons 进行编译。 一、编写代码 在 ubuntu 上创建一个 C 文件 hello.c 并加入如下代码&#xff1a; #include &…

【MATLAB画图】如何绘制图像坐标系

首先我们需要图像坐标轴的原点在左上角&#xff1a; set(gca,ydir,reverse,xaxislocation,top); 然后我们需要坐标轴上加上箭头 quiver(0, 0, 0, 520); % 在(x1, y1)处绘制一个箭头&#xff0c;其方向和长度由(dx, dy)确定 quiver(0, 0, 700, 0); % 在(x1, y1)处绘制一个箭头…

英语新概念2-回译法-lesson13

The Greenwood Boys 绿林少年是一组流行歌手们。现在他们正在参观城市里的所有公园&#xff0c;他们明天就要到这。他们将坐火车到并且大多数小镇上的年轻人将要欢迎他们&#xff0c;明天晚上他们将要在工人俱乐部唱歌。绿林少年将在这待五天&#xff0c;在这期间&#xff0c;…

flowable一对并发网关跳转的分析

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

iptables配置防火墙策略

背景 虚机安全非常重要&#xff0c;防火墙策略是安全中重要一环。常见配置防火墙策略的手段有两种&#xff1a;iptables和firewalld。 iptables是操作系统内置的防火墙配置工具&#xff0c;firewalld是基于iptables的&#xff08;本质firewalld配置生效后还是转化成了iptable…

互联网摸鱼日报(2024-05-07)

互联网摸鱼日报(2024-05-07) 36氪新闻 又是被「三无产品」冠名的五一档&#xff1f; 特斯拉擎天柱已经进厂拣电池了&#xff0c;其他“机器打工人”赶得上吗&#xff1f; 左手收购、右手出海&#xff1a;再战港交所的美的集团急什么&#xff1f; 全国第一&#xff0c;常州是…

前端面试题大合集3----网络篇

目录 一、Http协议详解&#xff0c;http请求方式&#xff0c;http状态码 Http协议详解&#xff1a; http请求方式&#xff1a; http状态码&#xff1a; 常用的状态码&#xff1a; 其他常用状态码&#xff1a; 二、Http常见请求方式 三、Http协议与TCP协议的区别和联系 …

【STM32G474】利用Cpp编写STM32代码后,Cubemx修改配置后代码报错147个error,如何处理?

问题描述 打开Cubemx&#xff0c;添加TIM7用于定时器精准延时&#xff0c;生成代码后&#xff0c;Keil提示有147个error。 之前是Cubemx是没有问题的&#xff0c;是利用Cpp编写stm32&#xff08;将Keil改为Version6&#xff09;后才导致Cubemx配置失败&#xff1a; debug成功…

Mybatis进阶2

Mybatis进阶1-CSDN博客 Mybatis入门-CSDN博客 Mybatis入门2-CSDN博客 我们接下来要学习Mybatis的高级查询 我们先在数据库中准备我们需要的数据表 teacher表 课程表&#xff1a;与教师表是一对多的关系&#xff0c;所以有一个外键字段 学生表 由于学生表和课程表是多对多的…

《Python编程从入门到实践》day22

# 昨日知识点回顾 方法重构、驾驶飞船左右移动、全屏显示 飞船不移动解决&#xff0c;问题出在移动变量x更新 # Ship.pysnipdef update(self):"""根据移动标志调整飞船的位置"""# 更新飞船而不是rect对象的x值# 如果飞船右移的标志和飞船外接…

八股Day2 多线程

Day2 多线程 1.线程和进程的区别&#xff1f; 2.并发和并行的区别&#xff1f; 3.创建线程的四种方式 4.线程的run()和start()有什么区别 5.线程包含哪些状态&#xff0c;怎么变化的 6.新建T1 T2 T3三个线程&#xff0c;如何保证他们按顺序执行 7.Notify和notifyAll区别 8.Sle…

微信小程序Picker组件全面解析:如何优雅处理数组对象选择器【代码示例】

微信小程序Picker组件全面解析&#xff1a;如何优雅处理数组对象选择器【代码示例】 基本概念picker组件简介数组对象与picker 实战例演练数据准备picker配置数据绑定与处理显示选中结果 安全性与性能优化结语与讨论 在微信小程序开发中&#xff0c;picker组件扮演着至关重要的…

射频无源器件之电桥

一. 电桥的定义及作用 电桥主要用于实现微波大功率功放系统的功率合成分配,信号采集等功能,被广泛应用于中国及全球4G/5G基站、5G网络覆盖、北斗导航天线、车载高精度导航(无人驾驶)天线等。可将信号分成有相位差的两路,90度电桥相位差90,180度电桥相位差180。 常说的3d…

Redis学习2——SpringBoot整合Redis,Redis工具类

依赖和配置 pom.xml SpringBoot整合Redis&#xff0c;需要引入spring-boot-starter-data-redis依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>当…

使用poi生成word文件时,zip相关的报错

apache poi-检测到Zip Bomb解决方案_zip bomb detected! the file would exceed the max. -CSDN博客

stm32_RTC_2_HAL——stm32CudeMX

介绍 RTC&#xff08;实时时钟&#xff09;不仅仅提供计数功能&#xff0c;它是一个完整的时钟和日历模块&#xff0c;用于提供日期和时间信息。RTC 能够提供年、月、日、星期、时、分、秒等时间信息&#xff0c;并且通常具有闹钟功能&#xff0c;可以用于定时唤醒或触发事件。…

C++学习第十二天(继承)

1、继承的概念以及定义 继承的概念 继承机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行拓展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象程序设计的层次结构&#x…

STM32F103学习笔记 | 报错界面及解决方案 | 1.keil5中文注释的横竖(正与斜)问题

文章目录 一、报错界面二、解决方案参考文献 一、报错界面 二、解决方案 打开设置 在打开的设置选项卡中&#xff0c;图中Font显示的是这个软件当前设置的字体&#xff0c;可以看到字体是仿宋&#xff0c;这就是问题出现的原因&#xff0c;将之改成没有的字体就行了。 可以看…

算法精讲:冒泡排序

1.基本思想 以n个人站队为例,从第一个人开始,依次比较相邻的两个人是否逆序对,(高的在前,矮的在后),若逆序便交换两人,也就是第一个人与第二个人相比较,若逆序便交换两人,第二个人和第三个人比较,若逆序便交换两人,……,直到第n-1个人与第n个人比较为止。经过一轮…

用FPGA+DAC输出“心”形波

1.前言 之前在做信号处理的时候整了一下活&#xff0c;用FPGADAC&#xff08;数模转换器&#xff09;&#xff0c;输出了一个爱心形状的波形&#xff0c;今天整理资料的时候偶然发现了他&#xff0c;现在把他分享出来。当时将DAC的输出接在示波器上显示如下图所示&#xff1a; …