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

CompletableFuture.runAsync的多线程下异步操作

在这里插入图片描述

CompletableFuture.runAsync的多线程下异步操作

🧰业务使用场景

CompletableFuture.runAsync()​方法是Java中用于创建异步任务的工具,它可以在后台线程中执行指定的任务,并且可以在任务完成后返回结果或执行后续操作。这种方式可以实现多线程下的异步操作。

在多线程环境下,使用CompletableFuture.runAsync()​可以实现并发执行多个任务,提高程序的性能和效率。每个异步任务都会在独立的线程中执行,互不影响,从而可以充分利用多核处理器的性能。

❗需要注意的点

在使用CompletableFuture.runAsync()​方法创建异步任务时,需要注意以下几个问题:

  1. 共享变量的线程安全性:如果异步任务需要访问或修改共享的变量,需要确保对这些变量的访问是线程安全的。可以使用Atomic​类、synchronized​关键字、Lock​等方式来保证共享变量的线程安全性。
  2. 变量的可见性:在多线程环境下,不同线程对同一个变量的修改可能不会立即对其他线程可见。可以使用volatile​关键字来保证变量的可见性,或者通过CompletableFuture​的一些方法来确保任务之间的数据传递和可见性。
  3. 避免数据竞争:在多线程环境下,可能会出现数据竞争的情况,即多个线程对同一变量进行读写操作,导致数据不一致。需要谨慎设计并发操作,避免数据竞争问题的发生。
  4. 异常处理:异步任务可能会抛出异常,需要在适当的地方捕获和处理异常,以避免程序崩溃或出现未知错误。
  5. 线程池的使用CompletableFuture.runAsync()​默认使用ForkJoinPool.commonPool()​来执行任务,如果需要更精细地控制线程池的大小或其他属性,可以使用CompletableFuture.supplyAsync()​方法并传入自定义的Executor​来创建异步任务 。
📝代码示例
package com.fjh.demo.thread;import com.fjh.demo.dto.scope.ResultView;
import com.fjh.demo.util.DynamicDataUtil;import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;/*** @ClassName: CompletableFutureDemo* @Description: TODO 多线程下异步操作* @Author: fengjiahao* @Date: 2024/6/15 16:01*/
public class CompletableFutureDemo {public static ResultView resultView;public static void main(String[] args)throws Exception {CompletableFutureDemo demo = new CompletableFutureDemo();//随机生成数据,该工具类可以自己实现ResultView 和DynamicDataUtil都是自己实现resultView = DynamicDataUtil.generateRandomObject(ResultView.class);//开启两个线程同时处理Thread thread1 =  new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"开始处理");demo.syncHandle();}});Thread thread2 =  new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"开始处理");demo.syncHandle();}});thread1.setName("线程1");thread2.setName("线程2");thread1.start();thread2.start();}public void syncHandle()  {System.out.println(resultView.toString());//线程可见性,共享(如果需要线程私有那么就需要使用到ThreadLocal,视场景采用)AtomicReference<ResultView> viewAtomic = new AtomicReference<>(resultView);CompletableFuture.runAsync(() -> {ResultView view= viewAtomic.get();view.setName(Thread.currentThread().getName());System.out.println("异步修改后:"+view.toString());try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}});System.out.println("修改后:"+resultView.toString());try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("修改后:"+resultView.toString());}}
  • 🪲结果

    
    线程2开始处理
    线程1开始处理
    ResultView{id=87, name='孙赵', amount=0.7525627958447209}
    ResultView{id=87, name='孙赵', amount=0.7525627958447209}
    修改后:ResultView{id=87, name='孙赵', amount=0.7525627958447209}
    修改后:ResultView{id=87, name='孙赵', amount=0.7525627958447209}
    异步修改后:ResultView{id=87, name='ForkJoinPool.commonPool-worker-9', amount=0.7525627958447209}
    异步修改后:ResultView{id=87, name='ForkJoinPool.commonPool-worker-2', amount=0.7525627958447209}
    修改后:ResultView{id=87, name='ForkJoinPool.commonPool-worker-2', amount=0.7525627958447209}
    修改后:ResultView{id=87, name='ForkJoinPool.commonPool-worker-2', amount=0.7525627958447209}

相关文章:

  • Linux-黑马程序员
  • 最大连续子序列和问题详解
  • Java课设项目
  • Docker Nginx
  • C++访问Private,Protecd的一些方法总结
  • 数据分析的流程是啥样?
  • web前端教程全套:从入门到精通的全方位探索
  • Rust 异步 trait 的实现困难
  • 【linux】认识“文件”的本质,理解“文件系统”的设计逻辑,体会linux优雅的设计理念
  • FreeBSD jail里面pkg 无法update、search和install
  • 零基础到高手蜕变:一步到位Jupyter Notebook安装全攻略
  • Wifi通信协议:WEP,WPA,WPA2,WPA3,WPS
  • C++设计模式——Decorator装饰器模式
  • OpenCV 4.10 发布
  • SpringBoot使用jasypt实现数据库信息的脱敏,以此来保护数据库的用户名username和密码password(容易上手,详细)
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【翻译】babel对TC39装饰器草案的实现
  • extract-text-webpack-plugin用法
  • flutter的key在widget list的作用以及必要性
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • JavaScript设计模式与开发实践系列之策略模式
  • Java深入 - 深入理解Java集合
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • React的组件模式
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 关于springcloud Gateway中的限流
  • 精彩代码 vue.js
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 前端工程化(Gulp、Webpack)-webpack
  • 设计模式 开闭原则
  • 深入浏览器事件循环的本质
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • 昨天1024程序员节,我故意写了个死循环~
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #if 1...#endif
  • ${factoryList }后面有空格不影响
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (C++)八皇后问题
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)计算机毕业设计ssm电影分享网站
  • (七)Knockout 创建自定义绑定
  • (十三)Flask之特殊装饰器详解
  • (转载)Google Chrome调试JS
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .form文件_SSM框架文件上传篇
  • .gitignore文件设置了忽略但不生效
  • .NET Core WebAPI中封装Swagger配置
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .NET MVC之AOP
  • .Net 高效开发之不可错过的实用工具
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值