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

CopyOnWriteArrayList 源码解读

一、CopyOnWriteArrayList 源码解读

JUC 中,对于 ArrayList 的线程安全用法,比较推崇于使用 CopyOnWriteArrayList ,那 CopyOnWriteArrayList是怎么解决线程安全问题的呢,本文带领大家一起解读下 CopyOnWriteArrayList 的源码,主要对几个常用的函数进行讲解。

在进行 CopyOnWriteArrayList 的源码讲解之前,先看下同样实现了线程安全的 Vector ,很多文章都说不推荐使用 Vector ,其主要原因是性能太差了,那性能为什么这么差呢?可以看下 Vector addget 的源码:

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

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

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

首先看下 CopyOnWriteArrayList 的全局变量有哪些:

在这里插入图片描述

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

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

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

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

在这里插入图片描述

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

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

在进行 remove 删除时,先使用 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 时,需要考虑下自己的数据量以及读写的频次。

相关文章:

CopyOnWriteArrayList 源码解读

一、CopyOnWriteArrayList 源码解读 在 JUC 中,对于 ArrayList 的线程安全用法,比较推崇于使用 CopyOnWriteArrayList ,那 CopyOnWriteArrayList是怎么解决线程安全问题的呢,本文带领大家一起解读下 CopyOnWriteArrayList 的源码…...

方法

方法方法(函数)一、课前问答二、方法和函数三、方法的参数3.1 单个参数3.2 多个参数四、方法的返回值五、方法的多级调用六、递归方法(函数) 一、课前问答 1、break和continue的区别 2、嵌套循环的执行流程 3、二进制有哪些运算&…...

C/C++实现发送邮件功能(附源码)

C++常用功能源码系列 本文是C/C++常用功能代码封装专栏的导航贴。部分来源于实战项目中的部分功能提炼,希望能够达到你在自己的项目中拿来就用的效果,这样更好的服务于工作实践。 专栏介绍:专栏讲本人近10年后端开发常用的案例,以高质量的代码提取出来,并对其进行了介绍。…...

Java虚拟机JVM-运行时数据区域说明

及时编译器 HotSpot虚拟机中含有两个即时编译器,分别是编译耗时短但输出代码优化程度较低的客户端编译器(简称为C1)以及编译耗时长但输出代码优化质量也更高的服务端编译器(简称为C2),通常它们会在分层编译…...

修复电子管

年前在咸鱼捡漏买到了10根1G4G电子管,这是一种直热三极管,非常的少见。买回来的时候所有的灯丝都是通的,卖家说都是新的,库存货,但是外观实在是太糟糕了,看着就像被埋在垃圾场埋了几十年的那种,…...

【Java】反射机制和代理机制

目录一、反射1. 反射概念2. 反射的应用场景3. 反射机制的优缺点4. 反射实战获取 Class 对象的四种方式二、代理机制1. 代理模式2. 静态代理3. 动态代理3.1 JDK动态代理机制1. 介绍2.JDK 动态代理类使用步骤3. 代码示例3.2 CGLIB 动态代理机制1.介绍2.CGLIB 动态代理类使用步骤3…...

synchronized底层

Monitor概念一、Java对象头二、Monitor2.1、Monitor—工作原理2.2、Monitor工作原理—字节码角度2.2、synchronized进阶原理(优化)2.3、synchronized优化原理——轻量级锁2.4、synchronized优化原理——锁膨胀2.5、synchronized优化原理——自旋优化2.6、…...

数据结构:复杂度的练习(笔记)

数据结构:复杂度的练习(笔记) 例题一: 可以先给数组排序,然后再创建一个i值,让他循环一次一次,遍历这个排序后的数组,但如果用qsort函数进行排序,时间复杂度就和题目要求…...

JAVA练习69- 从前序与中序遍历序列构造二叉树

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 提示:这里可以添加本文要记录的大概内容: 3月5日练习内容 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目-从…...

brew安装问题

最近使用mac安装了Python和PyCharm,使用python中的绘制图像的turtle库后,执行报错: import _tkinter # If this fails your Python may not be configured for Tk ModuleNotFoundError: No module named _tkinter 查询后需在mac 命令行执行&…...

【数据挖掘与商务智能决策】第一章 数据分析与三重工具

numpy基础 numpy与数组 import numpy as np # 用np代替numpy,让代码更简洁 a [1, 2, 3, 4] # 创建列表a b np.array([1, 2, 3, 4]) #从列表ach print(a) print(b) print(type(a)) #打印a类型 print(type(b)) #打印b类型[1, 2, 3, 4] [1 2 3 4] <class ‘list’>…...

计算机底层:BDC码

计算机底层&#xff1a;BDC码 BDC码的作用&#xff1a; 人类喜欢十进制&#xff0c;而机器适合二进制&#xff0c;因此当机器要翻译二进制给人看时&#xff0c;就会进行二进制和十进制的转换&#xff0c;而常规的转换法&#xff08;k*位权&#xff09;太麻烦。因此就出现了不同…...

【C++】平衡二叉搜索(AVL)树的模拟实现

一、 AVL树的概念 map、multimap、set、multiset 在其文档介绍中可以发现&#xff0c;这几个容器有个共同点是&#xff1a;其底层都是按照二叉搜索树来实现的&#xff0c;但是二叉搜索树有其自身的缺陷&#xff0c;假如往树中插入的元素有序或者接近有序&#xff0c;二叉搜索树…...

[2019红帽杯]childRE

题目下载&#xff1a;下载 参考&#xff1a;re学习笔记&#xff08;24&#xff09;BUUCTF-re-[2019红帽杯]childRE_Forgo7ten的博客-CSDN博客 这道题涉及到c函数的修饰规则&#xff0c;按照规则来看应该是比较容易理解的。上面博客中有总结规则&#xff0c;可以学习一下。 载…...

2D图像处理:九点标定_下(机械手轴线与法兰轴线不重合)(附源码)

文章目录 2. 机械手轴线与法兰轴线不重合2.1 两次拍照避免标定旋转中心2.2 旋转中心标定2.3 非标定中心的方法2.3.1 预备内容-点坐标旋转计算2.3.2 工件存在平移和旋转3. 代码(待更新)上一篇:2D图像处理:九点标定_上(机械手轴线与法兰轴线重合)(附源码) 2. 机械手轴线…...

【二分查找】分巧克力、机器人跳跃、数的范围

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...

Hyperf使用RabbitMQ消息队列

Hyperf连接使用RabbitMQ消息中间件 传送门 使用Docker部署RabbitMQ&#xff0c;->传送门<使用Docker部署Hyperf&#xff0c;->传送门-< 部署环境 安装amqp扩展 composer require hyperf/amqp安装command命令行扩展 composer require hyperf/command配置参数 假…...

【Linux】P3 用户与用户组

用户与用户组root 超级管理员设置超级管理员密码切换到超级管理员sudo 临时使用超级权限用户与用户组用户组管理用户管理getentroot 超级管理员 设置超级管理员密码 登陆后不会自动开启 root 访问权限&#xff0c;需要首先执行如下步骤设定 root 超级管理员密码 1、解除 roo…...

Spring核心模块——Aware接口

Aware接口前言基本内容例子结尾前言 Spring的依赖注入最大亮点是所有的Bean对Spring容器对存在都是没有意识到&#xff0c;Spring容器中的Bean的耦合度是很低的&#xff0c;我们可以将Spring容器很容易换成其他的容器。 但是实际开发的时候&#xff0c;我们经常要用到Spring容…...

Linux网络编程 第六天

目录 学习目标 libevent介绍 libevent的安装 libevent库的使用 libevent的使用 libevent的地基-event_base 等待事件产生-循环等待event_loop 使用libevent库的步骤&#xff1a; 事件驱动-event 编写一个基于event实现的tcp服务器&#xff1a; 自带buffer的事件-buff…...

揭秘Nunchaku FLUX.1 CustomV3工作流:LoRA融合技巧让图片细节更丰富

揭秘Nunchaku FLUX.1 CustomV3工作流&#xff1a;LoRA融合技巧让图片细节更丰富 你是否曾经看着别人用AI生成的图片&#xff0c;惊叹于那些纤毫毕现的发丝、细腻柔和的皮肤质感、以及充满故事感的光影细节&#xff0c;而自己用同样的模型却总感觉差了点什么&#xff1f;画面好…...

实战演练:在快马平台标准化java环境中构建并部署一个留言板应用

实战演练&#xff1a;在快马平台标准化Java环境中构建并部署一个留言板应用 最近在做一个Java Web项目的原型开发时&#xff0c;发现环境配置总是最耗时的环节。特别是团队协作时&#xff0c;每个人的JDK版本、依赖管理工具都可能不同&#xff0c;导致"在我机器上能跑&qu…...

GitHub开源项目日报 · 2026年4月1日 · AI编程助手与语音模型引领榜单

本期榜单主要涵盖开发者工具、AI应用和实用库三大类项目。从终端编程助手到语音AI模型,从HTTP客户端到提示词资源库,展示了当前开源生态的多样化发展。超过10000星以上的项目有prompts.chat、Axios、Claude Code、Codex CLI、VibeVoice、Claude Code最佳实践指南、Claude Cod…...

ModTheSpire开源工具:5大核心策略提升Slay The Spire模组体验

ModTheSpire开源工具&#xff1a;5大核心策略提升Slay The Spire模组体验 【免费下载链接】ModTheSpire External mod loader for Slay The Spire 项目地址: https://gitcode.com/gh_mirrors/mo/ModTheSpire 一、环境部署与资源配置&#xff1a;从零开始的模组加载器搭建…...

Axure中文界面终极配置指南:3分钟免费实现Axure RP 9/10/11快速汉化

Axure中文界面终极配置指南&#xff1a;3分钟免费实现Axure RP 9/10/11快速汉化 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn …...

教授专栏204| 潘永安:成功研发新型光探测器,促进可编程光子学应用

港科大电子及计算机工程学系系主任及教授潘永安&#xff08;左&#xff09;丶博士生牛玥&#xff08;右&#xff09;于港科大光子器件实验室合照。可编程光子学利用光传送讯号&#xff0c;能达到比电子学更快丶更节能的运算。然而&#xff0c;现有片上功率监测器的性能不足&…...

【无线通信】多载波无线通信系统设计Matlab仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34a;个人信条&#xff1a;格物致知,完整…...

三步快速配置:极简二维码插件让你的浏览器变身智能跨设备助手

三步快速配置&#xff1a;极简二维码插件让你的浏览器变身智能跨设备助手 【免费下载链接】chrome-qrcode chrome-qrcode - 一个 Chrome 浏览器插件&#xff0c;可以生成当前 URL 或选中文本的二维码&#xff0c;或解码网页上的二维码。 项目地址: https://gitcode.com/gh_mi…...

Meshroom终极指南:从照片到3D模型的免费开源解决方案

Meshroom终极指南&#xff1a;从照片到3D模型的免费开源解决方案 【免费下载链接】Meshroom Node-based Visual Programming Toolbox 项目地址: https://gitcode.com/gh_mirrors/me/Meshroom Meshroom是一款革命性的开源3D重建软件&#xff0c;能够将普通照片自动转换为…...

HoYo-Glyphs:11款米哈游游戏文字字体,轻松打造你的专属游戏世界

HoYo-Glyphs&#xff1a;11款米哈游游戏文字字体&#xff0c;轻松打造你的专属游戏世界 【免费下载链接】HoYo-Glyphs Constructed scripts by HoYoverse 米哈游的架空文字 项目地址: https://gitcode.com/gh_mirrors/ho/HoYo-Glyphs 你是否曾被《原神》中蒙德教堂的哥特…...