CopyOnWriteArrayList源码解析

CopyOnWriteArrayList源码解析

文章目录

  • CopyOnWriteArrayList源码解析
    • 一、CopyOnWriteArrayList
    • 二、总结

一、CopyOnWriteArrayList

JUC 中,对于 ArrayList 的线程安全用法,比较推崇于使用 CopyOnWriteArrayList ,那么CopyOnWriteArrayList是怎么解决线程安全问题的呢,本文通过解析 CopyOnWriteArrayList 的源码,主要对几个常用的函数进行讲解。

在进行 CopyOnWriteArrayList 的源码讲解之前,先看下同样实现了线程安全的 Vector ,之所以不推荐使用 Vector ,主要是性能太差了,可以看下 Vectoradd()get() 的源码:
在这里插入图片描述
在这里插入图片描述

可以看到Vector 的添加和读取操作都被加上了 synchronized 锁,当并发情况下,因为锁的存在相当于变成了单线程的操作,所以效率肯定低,同样这样的优点就是保证了数据的唯一性,不会读取到脏数据。

下面再看下 CopyOnWriteArrayList 是如何解决并发问题的呢。

首先看下 CopyOnWriteArrayList 的全局变量有哪些:
在这里插入图片描述

其中 lock 锁就是每次在做写操作时,锁的句柄,array 就是具体存储数据的数组,注意这里的 arrayvolatile 所修饰,因此可以在并发情况下实现数据的可见性。

new 创建了一个 CopyOnWriteArrayList 时,如果是使用无参的构造函数,则将 array 的长度默认成 0 ,创建了一个空的数组。

在这里插入图片描述在这里插入图片描述

在使用 add() 添加数据时,先使用 lock.lock() 上锁,并获取到当前的 array 数组,然后对 array 进行 copyOf(),新的数组的长度是之前的长度 +1 ,这样才能存放当前新的值,将新值填充后,再替换掉旧的 array 数组后,释放当前锁。
在这里插入图片描述

在使用 get() 获取指定下边数据时,直接对当前的 array 进行操作:

在这里插入图片描述

在进行 remove() 删除时,先使用 lock.lock() 上锁,然后再获取当前的 array 数组,如果传入的 index 正好是最后一个,那么 numMoved 计算出来就是 0 ,则使用 copyOf() ,长度进行 -1 去除最后一个数据。否则传入的不是最后一个,先声明一个新的 array 数组,数组的长度就是旧的 arraylen - 1,再将 0index 的数据 arraycopy() 至新的 array 数组,然后再将 index + 1 后的再 arraycopy() 至新的 array 数组,最后将新的 array 数组替换旧的,然后释放锁。

在这里插入图片描述

二、总结

  1. new 新建一个 CopyOnWriteArrayList 后会生成一个数组 array 来存放添加的内容,如果是无参的构造函数,则 array 的长度为 0 ,添加数据时再进行扩容。同时会声明一个 ReentrantLock锁。
  2. 当进行 add() 操作时,先进行上锁,然后对当前的 array 进行 copyOf(),并且新的长度是之前的长度 +1 ,这样才能存放当前新的值,将新值填充后,再替换掉旧的 array 数组后,释放当前锁。
  3. 当使用 get() 获取数据时,无需上锁,直接读取当前 array 数组的指定位置。
  4. 当使用 remove() 时,同样先进行上锁,然后再获取当前的 array 数组,如果传入的 index 正好是最后一个,则使用 copyOf() ,长度进行 -1 ,否则的话先声明一个新的 array 数组,现将 0index 的数据 arraycopy() 至新的 array 数组,然后再将 index + 1 后的再 arraycopy() 至新的 array 数组,最后将新的 array 数组替换旧的,然后释放锁。
    读下来之后可以感觉出来 CopyOnWriteArrayList 的源码非常容易理解和阅读,同时也可以看出来,CopyOnWriteArrayList 实现了写写隔离,但读读是可以共享的,这就有可能出现当某个数据再修改时,读进行了操作,导致读取到的还是旧的数据。还有就是每次写操作都对数组进行 Copy ,假如数据量非常大的情况下,进行 Copy 消耗的资源则会进行 x 2 ,因此使用 CopyOnWriteArrayList 时,需要考虑下自己的数据量以及读写的频次。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTP2

HTTP 确认访问用户身份的认证 某些Web页面只想让特定的人浏览,或者干脆仅本人可见。为达到这个目标,必不可少的就是认证功能。 何为认证 计算机本身无法判断坐在显示器前的使用者的身份。进一步说,也无法确认网络的那头究竟有谁。可见,为了弄清究竟是谁在访问服务器,就…

【Unity3D】MAX聚合广告SDK——Pangle广告接入(成了!成了!)

Pangle, App Monetization Simplified 注册 登录 创建应用 创建广告单元 将其应用ID和广告ID关联到MAX广告。 下载Pangle Unity Plugin包,新建一个空工程(很重要) Unity版本2019.4.0f1 gradle plugin 4.2.0 gradle版本6.7.1 build_tools 34.…

Java17(LTS Long Term Support)特性

支持JDK17的主流技术框架 spring framework 6.xspringboot 3.xkafka 3.0(不在支持jdk8)jenkins 2.357(必须jdk11起步)James Gosling表示赶紧弃用Java8,使用性能最好的JDK17Chart GPT也推荐JDK17,从长期到性能来说。 JDK17的特性 …

JRT对历史表和$get实现

由于Cache没有什么表数据大了查询和插入性能下降的问题,而关系库在数据量上千万后会性能下降,之前关注点都是Java业务脚本化和开发部署简单,还没管关系库单表大问题和级联查询复杂后慢的问题,现在开始解决这俩问题,这是…

socket 一个完整的不错的示例

从客户端向服务器端发送信息时&#xff0c;在服务器端有打印显示&#xff1b; 检测环境常用&#xff0c;备份一下 0&#xff0c;公共头文件代码 //config.h#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #inc…

人工智能的影响与挑战

人工智能是指通过模拟人类智能的各种特性和功能的技术和系统。对于普通大众来说&#xff0c;人工智能的爆发效应还是来源于chatGPT的爆火&#xff0c;大家第一次有了强烈的惊叹和危机。实际上&#xff0c;人工智能已经发展多年&#xff0c;像GPT的发展可以追溯到2018年&#xf…

深度学习笔记《一》:keras_core.layers.Conv2D()

一、说明 卷积&#xff0c;池化&#xff0c;激活函数&#xff0c;这三者号称是深度神经网络的三驾马车&#xff1b;其中卷积是最复杂的一个&#xff0c;因此&#xff0c;对卷积这个东西需要精心认知&#xff0c;这样对后面学习大有帮助。本篇为系列博文&#xff0c;专门介绍Cer…

亮相史上规模最大高交会,Coremail展现邮件技术创新实力

11月19日&#xff0c;第二十五届中国国际高新技术成果交易会在深圳落下帷幕&#xff0c;作为国内邮件行业引领者&#xff0c;Coremail受邀参展。 展览现场&#xff0c;Coremail邮件解决方案及系列产品受到了众多参观者与业内人士的关注与好评。Coremail XT6邮件系统技术成熟&a…

Arcgis根据样本点的shp文件创建一定范围的圆

导入样本点和数据 在ArcToolbox中&#xff0c;找到 "Analysis Tools" -> "Proximity" -> "Buffer" 工具。&#xff08;"分析工具" -> "邻近性" -> "缓冲区" &#xff09; 导入样本点shp文件&#xff…

智能优化算法应用:基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.教与学算法4.实验参数设定5.算法结果6.参考文献7.…

8 款强大工具适合 Python 入门的你

Python是一种开源的编程语言&#xff0c;可用于Web编程、数据科学、人工智能以及许多科学应用。学习Python可以让程序员专注于解决问题&#xff0c;而不是语法。由于Python相对较小&#xff0c;且拥有各式各样的工具&#xff0c;因此比Java和C等语言更具优势&#xff0c;同时丰…

技术必备:接口自动化测试数据校验神器【JSonPath】

我们今天不讲如何开发一款自定义开发校验规则库&#xff0c;而是给大家分享一款在开发自定义校验规则库或者常规的接口自动化测试时&#xff0c;经常会用到的一款数据提取神器&#xff1a;JSonPath。 1. JSonPath介绍 JSonPath是一种简单的方法来提取给定JSON文档的部分内容。…

全网最全卡方检验汇总

一文整理了卡方检验全部内容&#xff0c;包括卡方检验的定义&#xff08;基本思想、卡方值计算、适用条件分析&#xff09;、卡方检验分类&#xff08;2*2四格表卡方、R*C表格卡方、配对卡方、卡方拟合优度检验、分层卡方&#xff09;、卡方检验如何分析&#xff08;数据格式、…

银行合规知识竞赛要怎么策划才高大上

合规是银行业务永恒的主题&#xff0c;也是银行发展的根本保障。加强合规知识的学习和理解是保障银行业务健康发展的基础。通过竞赛形式的开展&#xff0c;旨在增强员工对风险和合规的敏感度和关注度&#xff0c;推动全行合规水平全面提升。那么如何策划一场高水平的银行合规知…

尤鲁都斯巴格镇社工站开展“我的牙齿我爱护”儿童公益活动

为了提高儿童的口腔健康意识&#xff0c;尤鲁都斯巴格镇社工站于2023年11月20日在尤鲁都斯巴格镇第一小学开展了一场《我的牙齿我爱护》儿童公益活动。本次活动主要针对小学阶段的儿童&#xff0c;旨在通过口腔健康宣讲等形式&#xff0c;普及口腔保健知识&#xff0c;引导孩子…

鸿蒙原生应用/元服务开发-AGC分发如何生成密钥和和证书请求文件

HarmonyOS通过数字证书&#xff08;.cer文件&#xff09;和Profile文件&#xff08;.p7b文件&#xff09;等签名信息来保证应用的完整性&#xff0c;应用如需上架到华为应用市场必须通过签名校验。因此&#xff0c;开发者需要使用发布证书和Profile文件对应用进行签名后才能发布…

C语言:编程实现1!+2!+3!+4!+……+n!

分析&#xff1a; #include<stdio.h>//这是一个预处理指令&#xff0c;将stdio.h头文件包含到程序中&#xff0c;以便使用输入输出函数。 int main()//这是程序的主函数&#xff0c;是程序执行的入口点。 int i, a 1, t 0, n;//定义了整型变量i、a、t和n。其中&#x…

C/C++ 发送与接收HTTP/S请求

HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于传输超文本的协议。它是一种无状态的、应用层的协议&#xff0c;用于在计算机之间传输超文本文档&#xff0c;通常在 Web 浏览器和 Web 服务器之间进行数据通信。HTTP 是由互联网工程任务组&#xff08;IETF…

邮件群发:避免垃圾邮箱,提升营销效果

群发邮件为什么会进入垃圾邮箱呢&#xff1f;常见的原因有&#xff1a;邮件内容出现问题、域名和IP的信誉度不高、退订数或投诉过多等原因。所以&#xff0c;营销人员在做EDM的时候&#xff0c;应该把握方式技巧&#xff0c;才能获取良好的营销效果&#xff0c;避免邮件成为垃圾…

工具 | docker删除不使用的容器

工具 | docker删除不使用的容器 Docker 清理命令