开启多线程下变量共享与私有问题

开启多线程下变量共享与私有问题

🌵ThreadLocal和Atomic是Java中用于多线程编程的两个重要工具

ThreadLocal是一个线程局部变量,它为每个线程提供了独立的变量副本,确保每个线程都可以访问自己的变量副本而不会影响其他线程的变量。在多线程环境下,使用ThreadLocal可以避免线程安全问题。

Atomic是一组原子操作类,提供了一些常见的原子操作,如原子更新整型、原子更新引用等。在多线程环境下,使用Atomic可以保证操作的原子性,避免出现数据竞争和线程安全问题

🎯下面是一个简单的示例ThreadLocal和Atomic在多线程环境下的用法:

import java.util.concurrent.atomic.AtomicInteger;public class ThreadLocalAndAtomicExample {private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);private static AtomicInteger atomicInteger = new AtomicInteger(0);public static void main(String[] args) {for (int i = 0; i < 5; i++) {new Thread(() -> {int localValue = threadLocal.get();localValue++;threadLocal.set(localValue);int atomicValue = atomicInteger.incrementAndGet();System.out.println("ThreadLocal value: " + threadLocal.get() + " Atomic value: " + atomicValue);}).start();}}
}

在上面的示例中,我们创建了一个ThreadLocal变量和一个AtomicInteger变量,然后启动了5个线程,每个线程对这两个变量进行操作。通过输出结果可以看到,ThreadLocal变量在每个线程中独立维护了自己的值,而AtomicInteger变量则保证了操作的原子性。

总结来说,在多线程编程中,ThreadLocal可以用于保证每个线程拥有独立的变量副本,避免线程安全问题;而Atomic可以用于保证操作的原子性,避免数据竞争和线程安全问题。在实际开发中,我们可以根据具体需求选择合适的工具来保证多线程程序的正确性和性能。

🎯下面是一个类似的示例,多线程使用EasyExcel处理导出数据,使用ExecutorService、CountDownLatch、ThreadLocal和Atomic在多线程环境下的用法:

   public void exportAllApply(HttpServletResponse response, ApplyScope applyScope){SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");String fileName = "APPLY" + +"-"+Calendar.getInstance().getTimeInMillis()+".xlsx";List<ApplyExportVo> allApply = new ArrayList<>();try {ExcelWriter excelWriter = EasyExcel.write(fileName, ApplyExportVo.class).build();WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").build();int threadCount = 5;//默认开启五个线程ExecutorService executorService = Executors.newFixedThreadPool(threadCount);CountDownLatch latch = new CountDownLatch(threadCount);ThreadLocal<ApplyScope> threadLocalApply = ThreadLocal.withInitial(ApplyScope::new);AtomicLong updatePage = new AtomicLong(1);for (int i = 0; i < threadCount; i++) {int finalI = i+1;executorService.execute(() -> {ApplyScope localApply = threadLocalApply.get();BeanUtils.copyProperties(applyScope,localApply);while (true) {long currentPage = updatePage.getAndIncrement();//更新分页信息,需同步updatePage(localApply, currentPage);ApplyGeneralVo applyGeneralVo = this.queryApplyView(localApply);List<ApplyVo> applyList = applyGeneralVo.getApplyList();log.info("线程threadCount:"+finalI+"当前页码"+currentPage+",数量"+applyList.size());if(CollectionUtils.isEmpty(applyList)){break;}List<ApplyExportVo> exportVos = BeanUtil.toBeanList(applyList, ApplyExportVo.class);allApply.addAll(exportVos);}latch.countDown();});}executorService.shutdown();latch.await();Long startWrite = Calendar.getInstance().getTimeInMillis();Optional.ofNullable(allApply).ifPresent(data -> {excelWriter.write(data, writeSheet);});excelWriter.finish();log.info("----- writeExcelTime:" + (Calendar.getInstance().getTimeInMillis() - startWrite));} catch (Exception e) {e.printStackTrace();}
}private synchronized long updatePage(ApplyScope scope, long current){PageScope page = scope.getPages();if(page == null){page = new PageScope();page.setSize(1000L);page.setCurrent(current);scope.setPages(page);} else {page.setCurrent(current);}return page.getCurrent();
}

🚩在上面的示例中,我们创建了一个固定大小的线程池ExecutorService,并使用CountDownLatch来等待所有线程执行完毕。每个线程在执行时会对ThreadLocal变量和AtomicInteger变量进行操作,并在操作完成后调用CountDownLatch的countDown()方法来通知主线程。

通过输出结果可以看到,每个线程中的ThreadLocal变量和AtomicInteger变量都能够正确地保持独立和原子性,同时CountDownLatch确保了所有线程执行完毕后主线程才会继续执行。

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

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

相关文章

json-server 模拟接口服务

前端开发经常需要模拟接口请求&#xff0c;可以通过 json-server 实现。 1. 安装 json-server 在前端项目的终端命令行中执行 npm i json-server2. 创建数据源 在项目中新建文件 db.json &#xff0c;与 package.json 同级&#xff0c;内容为模拟的数据 注意 json 文件对格式…

选择步入式高低温试验室价格除外还需要考虑哪些方面?

选择步入式高低温试验室时&#xff0c;价格是一个非常重要的考虑因素。但是&#xff0c;步入式高低温试验室价格不仅仅是主要决定因素&#xff0c;我们还需要考虑到设备的性能、质量、可靠性以及售后服务等多方面因素。接下来给大家具体介绍的关于选择步入式高低温试验室价格除…

conan2 基础入门(06)-conanfile.py入门

conan2 基础入门(06)-conanfile.py入门 文章目录 conan2 基础入门(06)-conanfile.py入门⭐准备预备文件和Code ⭐使用流程指令 ⭐具体讲解conanfile.pyconan install END视频教学 ⭐准备 注意&#xff0c;如果想跟好的学习conanfile.py建议使用python来安装conan。 当然使用其…

shell 脚本curl的时候,变量未被正确替换

有问题的脚本&#xff1a; updateRes\$(curl --location --request PUT http://172.16.80.88:3100/api/application/devopsBuildVersion \--header Authorization: bGFtcF93ZWJfcHJvOmxhbXBfd2ViX3Byb19zZWNyZXQ \--header Content-Type: application/json;charsetUTF-8 \--…

C++入门系列-构造函数

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会…

Day 28 MySQL的数据备份与恢复

数据备份及恢复 1.概述 ​ 所有备份数据都应放在非数据库本地&#xff0c;而且建议有多份副本 备份&#xff1a; 能够防止由于机械故障以及人为误操作带来的数据丢失&#xff0c;例如将数据库文件保存在了其它地方 冗余&#xff1a; 数据有多份冗余&#xff0c;但不等备份&…

利用PyTorch实现概率建模和贝叶斯推断

1.PyTorch概率建模和贝叶斯推断 在 PyTorch 上进行概率建模和贝叶斯推断通常涉及以下几个关键步骤&#xff1a; 定义概率模型&#xff1a;首先&#xff0c;你需要定义一个概率模型&#xff0c;该模型描述了数据生成的过程。在 PyTorch 中&#xff0c;这通常涉及到定义模型的参数…

JVM---垃圾回收

目录 一、C/C的内存管理 二、Java的内存管理 三、垃圾回收的对比 四、Java的内存管理和自动垃圾回收 五、方法区的回收 手动触发回收 六、堆回收 如何判断堆上的对象可以回收&#xff1f; 引用计数法 可达性分析算法 五种对象引用 软引用 软引用的使用场景-缓存 弱引用 虚…

推荐算法详解

文章目录 推荐算法引言基于内容的推荐原理算法步骤注意点可以优化的地方示例代码讲解 协同过滤推荐原理算法步骤注意点可以优化的地方示例代码讲解 混合推荐系统原理算法步骤注意点可以优化的地方示例1代码讲解1示例2代码讲解2 基于知识的推荐原理算法步骤注意点可以优化的地方…

机柜风扇KTS011温湿度控制器KTO011风机控制温控器机械开关温控仪

品牌&#xff1a;威驰 型号&#xff1a;KTS011常开 产地&#xff1a;中国大陆 颜色分类&#xff1a;KTS011常开,KTO011常闭 KTS011与KTO011的区别 KTS011&#xff0c;常开型&#xff0c;可搭配风扇/风机使用&#xff1a;当环境温度超过温控器设定温度&#xff0c;温控…

数据结构与算法===贪心算法

文章目录 定义适用场景柠檬水找零3.代码 小结 定义 还是先看下定义吧&#xff0c;如下&#xff1a; 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最好或最优的算法。 适用场景 由于…

在线教育系统怎么留住用户,什么叫k12在线教育机构?它的价值是什么?

k12在线教育机构&#xff0c;近年来时常被人提起&#xff0c;当然&#xff0c;也有很多人对此不太熟悉&#xff0c;大众的印象仍然停留在传统教育的阶段&#xff0c;所以&#xff0c;什么叫k12在线?其实&#xff0c;弄的不太明白&#xff0c;所以&#xff0c;也来给各位科普下…

Kafka的安装及接入SpringBoot

环境&#xff1a;windows、jdk1.8、springboot2 Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/ 1.概述 Kafka 是一种高性能、分布式的消息队列系统&#xff0c;最初由 LinkedIn 公司开发&#xff0c;并于2011年成为 Apache 顶级项目…

C语言-课程管理系统-大作业

C语言编写课程管理系统 1 需求分析2 需要查的知识点3 数据结构和基础函数功能3.1 课程数据结构3.2 菜单和选择项3.3 从文件中加载课程信息到内存3.4 将内存中的课程信息保存到文件3.5 将输入的字符串格式化为课程信息结构体 4 主要功能函数4.1 录入课程信息函数4.2 浏览课程信息…

2024全新小狐狸AI免授权源码

源码安装说明&#xff1a; 下 载 地 址 &#xff1a; runruncode.com/php/19757.html 1. 在宝塔新建一个站点&#xff0c;选择 PHP 版本为 7.2、7.3 或 7.4。将压缩包上传到站点的根目录&#xff0c;并设置运行目录为 /public。 2. 导入数据库文件&#xff0c;该文件位于 …

gap意识

在学习的过程中&#xff0c;遇到一个知识点搞不懂&#xff0c;或是在工作的过程中&#xff0c;遇到一个难题解决不了&#xff0c;很多时候不是我们的能力不行或是智商不够&#xff0c;而是我们当前的认知与那个知识点或难题之间存在较大的 gap。比如&#xff0c;若没学过线性代…

最大9W升压型DCDC多串LED恒流驱动

描述 AP9234是一款由基准电压源、振荡电路、误差放大电路、相位补偿电路、电流限制电路等构成的CMOS升压型DC/DC LED驱动。由于内置了低导通电阻的增强型N沟道功率 MOSFET&#xff0c;因此适用于需要高效率、高输出电流的应用电路。另外&#xff0c;可通过在VSENSE端子连接电…

Python装饰器带括号和不带括号的理解

装饰器是 Python 中一个强大且灵活的特性&#xff0c;允许用户在不修改原有函数或类定义的基础上&#xff0c;为其增加额外功能。 今天在尝试自定义 Python 装饰器的时候遇到了一个问题&#xff0c;因为以前一直是使用装饰器&#xff0c;基本没有自定义过装饰器&#xff0c;所…

vue3点击添加小狗图片,vue3拆分脚本

我悄悄蒙上你的眼睛 模板和样式 <template><div class"XueXi_Hooks"><img v-for"(dog, index) in dog1List" :src"dog" :key"index" /><button click"addDog1">点我添加狗1</button><hr …

WPF之工具栏菜单栏功能区。

1&#xff0c;菜单栏&#xff0c;工具栏&#xff0c;状态栏。 1.1&#xff0c;Menu中可添加菜单分隔条<Separator></Separator>作为分割线&#xff0c;使用Separator可以通过改变其template来自定义&#xff0c;Separator是无焦点的&#xff0c;如果简单的在MenuIt…