不要在线上滥用CopyOnWriteArrayList,姿势不对性能真的很拉胯

news2024/11/17 23:57:00

从JDK1.5版本,JAVA提供了线程安全的List增强版CopyOnWriteArrayList,其保持线程安全的方式是:每次修改数据时,不会直接修改数据,而是把数据复制出来一份,对复制出来的数组进行操作。

通过这样的机制,可以极大程度的提升读的并发性能,所以对于CopyOnWriteArrayList来说,非常适合读多写少或者无锁的场景。

但是,如果我们为了炫技而不分场合滥用CopyOnWriteArrayList的话,可能会带来适得其反的结果。

下面,我们通过一段测试代码,比较一下CopyOnWriteArrayList和普通加锁ArrayList的读写性能差距。

我们首先测试一下写性能的差距:构建一个CopyOnWriteArrayList和synchronizedList,通过多线程并发写入100000个元素。

List<Integer> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
//构建一个加锁的List
List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
StopWatch stopWatch = new StopWatch();
int loopCount = 100000;
stopWatch.start("测试写性能:copyOnWriteArrayList");
//多线程写入100000个数字
IntStream.rangeClosed(1, loopCount).parallel()
  .forEach(x -> copyOnWriteArrayList.add(ThreadLocalRandom.current().nextInt(loopCount))
          );
stopWatch.stop();
stopWatch.start("测试写性能:synchronizedList");
//多线程写入100000个数字
IntStream.rangeClosed(1, loopCount).parallel()
  .forEach(x -> synchronizedList.add(ThreadLocalRandom.current().nextInt(loopCount))
          );
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
Map<String, Integer> result = new HashMap<>();
result.put("copyOnWriteArrayList", copyOnWriteArrayList.size());
result.put("synchronizedList", synchronizedList.size());
System.out.println(JSON.toJSONString(result));

可以清楚的看到,在大量写的情况下,CopyOnWriteArrayList的性能是远远不如普通的加锁List的,性能差距可能在100倍以上。

而之所以CopyOnWriteArrayList的写入这么慢,就是因为CopyOnWriteArrayList每次写入都要对存放元素的旧数组进行复制创建一个新数组,从而导致内存申请释放消耗很大。

我们再测试一下大量读的性能差距:先对两个List写入100000个元素,再通过多线程的方式随机get元素。

List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
synchronizedList.addAll(IntStream.rangeClosed(1, 100000).boxed().collect(Collectors.toList()));

List<Integer> copyOnWriteArrayList = IntStream.rangeClosed(1, 100000).boxed()
  .collect(Collectors.toCollection(CopyOnWriteArrayList::new));

StopWatch stopWatch = new StopWatch();
int loopCount = 1000000;
int count = copyOnWriteArrayList.size();
stopWatch.start("测试读性能:copyOnWriteArrayList");
IntStream.rangeClosed(1, loopCount).parallel().forEach(
  x -> copyOnWriteArrayList.get(ThreadLocalRandom.current().nextInt(count))
);
stopWatch.stop();
stopWatch.start("测试读性能:synchronizedList");
IntStream.range(0, loopCount).parallel().forEach(
  x -> synchronizedList.get(ThreadLocalRandom.current().nextInt(count))
);
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
Map<String,Integer> result = new HashMap<>();
result.put("copyOnWriteArrayList", copyOnWriteArrayList.size());
result.put("synchronizedList", synchronizedList.size());
System.out.println(JSON.toJSONString(result));

经过多次测试,CopyOnWriteArrayList的读性能大概在普通加锁List的2-5倍左右。

而CopyOnWriteArrayList的读之所以快,是因为CopyOnWriteArrayList读取元素是无锁状态下直接按数组下标获取。

一般来说,CopyOnWriteArrayList只适用于大量读的场景,如果有了大量写操作,性能反而不如普通的List。

JDK为我们提供了很多用于并发场景的工具类,但是仍需要我们仔细了解每一种工具的使用场景,在不合适的场景使用不合适的工具,会导致性能更差。

写文不易,感谢您的点赞和关注。

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

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

相关文章

【图像算法】马赛克识别

【目的】 校验视频中出现马赛克的频率&#xff0c;抽象成将视频切割成图片&#xff0c;对每张代测图片进行自动化验证。 【实现】 图像边缘检测算法识别 算法步骤&#xff1a; 使用高斯滤波器&#xff0c;以平滑图像&#xff0c;滤除噪声。计算图像中每个像素点的梯度强度和…

buuctf-web-[BJDCTF2020]Easy MD51

打开环境一个简单的页面查看源代码一个get传参&#xff0c;随便输入试试看输入1,1",1,均无反应&#xff0c;每次遇到这种有输入框的都以为是sql注入&#xff0c;但是题目为md5标头里面看到提示select * from admin where passwordmd5($pass,true)搜索相关漏洞&#xff0c;…

gost 常用tunnel配置示例(隧道模式)

gost是用golang语言实现的一个安全隧道。地址位于&#xff1a;https://github.com/ginuerzh/gost是一个不可多得的隧道工具。至于什么是隧道&#xff1f; 就是可以通过这个工具传输一些其他协议的数据。就像这个样子。隧道有什么用呢&#xff1f;可以起到一些加速的作用或者流量…

Array.prototype.from()

Array.from() 用于将类数组对象或可迭代对象转化为一个新的浅拷贝数组实例。 let arr Array.from({length:3},(_,i)>({id:item-${i1}}))console.log(arr)Array.from()转换数组 // Array.from 转换成数组let arr2 Array.from(chixinAwen)console.log(arr2) 示例&#xff1a…

如何免安装使用 Python?推荐 17 个在线的 Python 解释器

安装 Python 很容易&#xff0c;但或许你正在用智能手机/平板电脑&#xff0c;在用不允许安装软件的电脑&#xff0c;或者因为其它原因无法安装 Python。那么&#xff0c;如何通过免安装的方式使用 Python 呢&#xff1f; 本文将介绍 17 个免费的 Python 解释器和交互式 Shell…

百里挑一,4款免费又实用的软件,用一次就爱上

好看的皮囊千篇一律&#xff0c;实用的软件百里挑一&#xff0c;下面几款软件都是笔者收集多年所得&#xff0c;实用且免费。 1、坚果云 这是一款颠覆许多人认知的网盘工具&#xff0c;免费使用无广告&#xff0c;不限速的优点就比某度网盘强百倍&#xff0c;支持任何设备&…

AOP案例:测量业务层接口万次执行时间

测量业务层接口万次执行时间1. 准备1.1 service层&#xff1a;1.2 dao层&#xff1a;1.3 SpringConfig配置类&#xff1a;2. AOP2.1 通知类2.2 测试类&#xff1a;3. 问题及改进1. 准备 需求&#xff1a;任意业务层接口执行均可显示执行的时长&#xff1b; 切入点配置&#x…

(day9) 自学Java——常用API

AIP就是Java已经写好的各种功能的java类 目录 1.Math 2.System 3.Runtime 4.Object 5.对象工具类Objects 6.BIgInteger 7.BigDecima 8.正则表达式 (1)爬虫 (2)带条件爬取&#xff0c;贪婪爬取和识别正则的两个方法 (3)捕获分组和非捕获分组 9.JDK7以前时间相关类 …

一起自学SLAM算法:12.3 autoware导航系统

连载文章&#xff0c;长期更新&#xff0c;欢迎关注&#xff1a; 上面介绍的ros-navigation和riskrrt导航系统主要都是用于机器人的低速导航&#xff0c;并且大多基于2D地图。而autoware导航系统主要用于无人驾驶汽车的高速导航&#xff0c;并且基于3D地图。除了所导航速度高一…

软件工程(一)——软件开发模型和方法

目录 &#xff08;一&#xff09;软件开发方法 &#xff08;二&#xff09;瀑布模型 &#xff08;三&#xff09;原型模型 &#xff08;四&#xff09;螺旋模型与增量模型 &#xff08;五&#xff09;V模型、喷泉模型、RAD模型 (六) 统一过程&#xff08;RUP&#xff09; …

idea 中 connot run program “svn“ 系统找不到文件

idea 中 connot run program “svn“ 系统找不到文件1. idea中svn的问题1.1 idea connot run program "svn"1.1.1 解决办法-重装svn1.2 idea中check out灰色不可用1.2.1 解决办法—装插件1. idea中svn的问题 1.1 idea connot run program “svn” 如图&#xff1a;…

2023年机床工具行业研究报告

第一章 行业概况 生产和销售机床工具的行业。机床是指制造机器的机器&#xff0c;亦称工作母机或工具机&#xff0c;习惯上简称机床。一般分为金属切削机床、锻压机床和木工机床等。现代机械制造中加工机械零件的方法很多&#xff1a;除切削加工外&#xff0c;还有铸造、锻造、…

【ES实战】索引生命周期管理(一)

索引生命周期管理IL&#xff2d;&#xff08;index lifecycle management&#xff09; 文章目录索引生命周期管理IL&#xff2d;&#xff08;index lifecycle management&#xff09;概述版本矩阵主要概念索引生命周期阶段的过渡阶段的执行生命周期中的操作生命周期策略索引翻滚…

AzureRT:一款能够实现各种Azure红队技战术的PowerShell模块

关于AzureRT AzureRT是一款能够实现各种Azure红队技战术的PowerShell模块&#xff0c;在AzureRT的帮助下&#xff0c;广大研究人员可以从攻击者的角度来与Azure和Azure AD进行交互&#xff0c;以此来测试目标环境的安全性。 AzureRT可以帮助广大研究人员测试和处理基于访问令…

【工具】操作PDF推荐的java依赖

Apache PDFBox |一个 Java PDF 库 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox-app</artifactId><version>2.0.27</version></dependency> Apache PDFBox - A Java PDF Library Apache PDFBox 库…

超详解线段树(浅显易懂)

一&#xff0c;什么是线段树&#xff1f;线段树是怎样的树形结构?线段树是一种二叉搜索树&#xff0c;而二叉搜索树&#xff0c;首先满足二叉树&#xff0c;即每个结点最多有两颗子树&#xff0c;并且是一颗搜索树&#xff0c;我们要知道&#xff0c;线段树的每个结点都存储了…

用于在过程工业中参数化配置现场设备的移动式解决方案

EndressHauser提供了一个组合套件&#xff08;包含Field Xpert和Softing的mobiLink通信工具&#xff09;&#xff0c;可用于参数化配置和现场调试。 &#xff08;将Softing的mobiLink通信工具与EndressHauser的Field Xpert SMT70或SMT77平板电脑相结合使用&#xff0c;可为用户…

再见 Matplotlib 和 Seaborn ,Python 画图建议用这个

本文主要介绍 Python 中用来替代 Matplotlib 和 Seaborn 的可视化工具 plotly&#xff0c;并结合实例讲解了 plotly 的优点和用法&#xff0c;满足了可视化绘图的交互需求。 数据可视化是人脑有效理解各种信息的最舒适、最直观的方式。对于需要处理数据的人来说&#xff0c;能…

谈思生物直播课|辛格迪副总裁“细胞治疗数字化解决方案”

近年来&#xff0c;细胞基因治疗在全球范围内得到了快速的发展。因为细胞基因治疗药物的特殊性&#xff08;从人体中采得活细胞&#xff0c;经过特别的处理技术后再输入人体&#xff09;&#xff0c;其安全性也被监管机构和药企高度关注&#xff1b;同时&#xff0c;也由于其制…

Laravel笔记-使用composer搭建Laravel环境(开发工具phpStorm)

以前写过一个&#xff0c;但没这个composer直接搭建的方便。在此记录下。 使用国内的 Composer 加速镜像 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 新建一个名为MyRestfulTest的项目&#xff1a; composer create-project larave…