CopyOnWriteArrayList简介

news2024/11/16 5:26:38

1. 简介

CopyOnWriteArrayListArrayList 的线程安全版本

就是在进行写操作的时候会 copy 原数组,然后写完将指针指向新的数组,是一种读写分离的思想,可以并发的读,不能并发的写

优点:

  • 保证线程安全
  • 读取时不加锁,只是写入、删除、修改时加锁

缺点:

  • 内存占用问题:由于写时复制的机制,内存中会同时存在两份数组对象,如果老数组占了200MB,要写100MB数据进去,那么同时会占用500MB的内存,有可能会造成频繁的Yong GC和FUll GC
  • 数据一致性:

在这里插入图片描述

2. 实现原理

2.1 源码


final transient ReentrantLock lock = new ReentrantLock();

// 真正保存元素的数组
private transient volatile Object[] array;

2.2 原理

get(int index)

从源码可以看出 CopyOnWriteArrayList 在读操作的时候并没有并发控制,所以读数据的性能不受影响

// 获取指定下标的元素
public E get(int index) {
		return get(getArray(), index);
}

final Object[] getArray() {
        return array;
 }

add(E e)

在读操作的时候使用了ReentrantLock来进行并发控制,

  1. add 时先加 ReentrantLock
  2. 然后复制当前的数组
  3. 在新数组上进行新增操作
  4. 将数组引用指向新数组
// 将指定的元素追加到此列表的末尾
public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
}

3.疑问

💡 线程A在读数组时,线程B同时在修改数组,并且在A读取数组的时候已经修改完成,此时会影响到线程A读取数组吗?

结果:不影响

因为JAVA的参数传递机制,线程A在get操作中是通过全局 array指针的副本去访问存放在堆内存中的数组,即使线程B在堆中创建了一个新的数组,并且改变了全局array 指向的内存地址,也不会影响到指针副本的值,指向的还是原来的内存空间,读的也还是旧数组

4.拓展

Arrays.copyOf

简介:

Arrays.copyOf(T[] original, int newLength) 的作用是复制数组

相当于数组本身来说,是深拷贝

但是对于数组存储的元素来说,除了元素类型为基本类型、包装类、String类为深拷贝,其他都为浅拷贝

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

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

相关文章

基于PyQt5的图形化界面开发——自制MQTT客户端软件

基于 PyQt5 的图形化界面开发——自制MQTT客户端 0. 前言1. 第三方库的安装及注意事项2. Editor.py2.1 配置界面效果演示: 3. Publish.py3.1 消息发布界面演示 4. Subcribe.py4.1 订阅消息效果演示: 界面切换——main.py5. 写在最后 0. 前言 使用 PyQt5…

葛兰一季度规模再度跌破900亿

一季度末管理规模再度跌破900亿元,中欧基金葛兰交出了公募主动权益基金管理规模的头把交椅。 4月22日零点刚过,葛兰在管基金悉数披露2023年一季报,从管理规模来看,一季度葛兰在管5只公募基金合计规模降至844.40亿元,较…

keep-alive 和 router-view 的使用方法(Vue3)

系列文章目录 提示:主要是介绍keep-alive 和 router-view在Vue3中的使用方法,以及适用场景!!! 文章目录 系列文章目录前言:一、router-view:1. 常规使用方法2. 非常规使用方法(插槽&…

UE5语音识别和语音合成-阿里云智能语音-短视频-翻译-文章-AI角色等

UE5智能语音 哈喽,大家好,我叫人宅,很高兴和大家一起分享本套课程,阿里云智能语音UE5版本开发。阿里云智能语音一共分为 语音合成,语音识别,什么是语音合成,它可以将您的文字转化成您设定的任何…

大数据数仓维度建模

目录 维度建模分为三种: 1、星型模型: 2、雪花模型: 3、星座模型: 模型的选择: 维度表和事实表: 维度表: 维度表特性 : 事实表: 事实表特性: 事务型…

程序员能干多久?程序员能干到多大年龄?

程序员可以工作多少年?大多数程序员认为程序员是吃青春饭的工作。编程只能干到30岁,最长可达35岁。我经常听到这样的话,都让人倍感压力。今天,我们来谈谈这个老话题...... 程序员能干多久? 根据国外的经验来说,干到…

ChatGPT 基础使用方法

文章目录 1. ChatGPT 是下一代搜索引擎2. ChatGPT 是学习助手3. ChatGPT API 简介4. ChatGPT API 身份5. 开发痛点6. 机会与前景7. Images8. Audio 1. ChatGPT 是下一代搜索引擎 根据 3 月份对 ChatGPT 的使用,我对它的理解是下一代的搜索引擎,即能够根…

【社区图书馆】读《大话数据结构溢彩加强版》

目录 书中简介: 选读原因 本书内容有哪些: 学会了什么: 书中简介: 《大话数据结构【溢彩加强版】》以一个计算机教师的教学过程为场景,讲解数据结构和相关算法的知识。全书以趣味方式来叙述,大量引用各…

无公网IP,外网远程连接MySQL数据库

哈喽~大家好,这篇来看看无公网IP,外网远程连接MySQL数据库。 文章目录 前言1. 检查mysql安装状态2. 安装配置cpolar内网穿透3. 创建tcp隧道,映射3306端口4. 公网远程连接4.1 图形化界面4.2 使用命令行远程连接 5. 配置固定tcp端口地址5.1 保留…

「计算机控制系统」6. 直接设计法

特殊类型系统的最小拍无差设计 一般系统的最小拍无差设计 最小拍控制器的工程化改进 Dahlin算法 文章目录 特殊类型系统的最小拍无差设计理论分析典型输入函数的最小拍无差系统 一般系统的最小拍无差设计有波纹最小拍无差设计无波纹最小拍无差设计 最小拍控制器的工程化改进针对…

操作HDFS文件系统常用命令(启停、创建、查看、上传、下载、追加、删除.etc)

文章目录 1 一键启停2 单进程启停3 创建文件夹4 查看指定目录下内容5 上传文件到HDFS指定目录下 linux->HDFS6 下载 HDFS ->Linux7 追加数据 linux->HDFS8 查看HDFS文件内容9 HDFS 数据删除10 网页端图形化界面11总结 跟linux命令大差不差 1 一键启停 HadoopHDFS组件…

共享锁中:Semaphore 、CyclicBarrier 、CountDownLatch的区别是什么?

目录 下面是一个使用Semaphore实现共享锁的例子: 下面是一个使用CountDownLatch实现等待一组操作完成的例子: 下面是一个使用CyclicBarrier实现等待一组线程达到某个状态后再同时执行的例子: 结论1: 结论2: 下面是…

JavaSE基础(一)—— Java环境搭建、IDEA、Java语言

【JavaSE基础回顾笔记】 JavaSE基础(一)—— Java环境搭建、IDEA、Java语言 JavaSE基础(二)—— Java语法、运算符、随机数 JavaSE基础(三)—— 分支、循环、控制关键字 JavaSE基础(四&…

Opencv+Python笔记(六)图像的平滑处理

图像在获取、传输的过程中,可能会受到干扰的影响,会产生噪声,噪声是一种出错了的信号,噪声会造成图像粗糙。 图像平滑处理的目的是去除图像中的噪声和不必要的细节,使图像更加清晰和易于分析。常用的平滑滤波器包括高斯…

无感FOC

前言 一年多前就画好了FOC的板子,后面因为各种原因耽搁了,最近又重新捡起来,准备写一下程序,首先我们要做一下FOC的理论分析。 左右手定则 左手定则用于判断导线在磁场中受力的方向: 磁感线从左手手心流入&#xff0…

前++与后++的区别?反汇编底层刨析

目录 1.只,不赋值 2.和其他运算符的结合 1.后置(i) 2.前(i) 总结 1.只,不赋值 前置和后置无区别,效果一致,i -> ii1 反汇编语言内,对a和b的操作进行观察&#…

彻底卸载Anaconda和PyCharm详细教程

目录 一、卸载Anaconda 二、 卸载PyCharm 一、卸载Anaconda 1、在开始处打开Anaconda Prompt 2、打开后,输入conda install tqdm -f命令并按回车键 conda install tqdm -f 3、之后页面会出现一个WANNING,这个我们不用在意,然后会出现一个…

GitHub新手用法详解【适合新手入门-建议收藏!!!】

目录 什么是Github,为什么使用它? 一、GitHub账号的注册与登录 二、 gitbash安装详解 1.git bash的下载与安装 2.git常用命令 3. Git 和 GitHub 的绑定 1. 获取SSH keys 2.绑定ssh密钥 三、通过Git将代码提交到GitHub 1.克隆仓库 2.测试提交代码…

ClickHouse同步MySQL数据

目录 1 概述1.1 特点1.2 使用细则 2 案例实操2.1 MySQL 开启 binlog 和 GTID 模式2.2 准备 MySQL 表和数据2.3 开启 ClickHouse 物化引擎2.4 创建复制管道2.5 修改数据2.6 删除数据2.7 删除表 1 概述 MySQL 的用户群体很大,为了能够增强数据的实时性,很多…

通过response.body()返回的json报文,直接生成对应结构体,实现数据绑定

作者:非妃是公主 专栏:《Golang》 博客地址:https://blog.csdn.net/myf_666 个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩 文章目录 序一、解决办法二、相关测试代码1. json body…