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

线程安全集合——CopyOnWriteArrayList

文章目录

  • 前言
  • 一、CopyOnWriteArrayList是什么?
  • 二、如何使用
  • 三、底层方法实现
    • 3.1 add()
    • 3.2 remove()
    • 3.3 set()
    • 3.4 get()


前言

一、CopyOnWriteArrayList是什么?

CopyOnWriteArrayList是一个线程安全的集合,是List接口的实现类。它是用ReentrantLock来保证线程安全的,其用法和List接口下其他的实现类相差不大。


二、如何使用

public static void main(String[] args) {// List接口下线程安全的集合CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();// 修改操作(加锁)// 1. 添加list.add("a");list.add("b");list.add("c");// 2. 删除list.remove(0);// 3. 修改list.set(1, "d");// 查询操作(不加锁)String s = list.get(1);System.out.println(s);System.out.println(list);}

三、底层方法实现

3.1 add()

源代码如下:

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();}}

实现概述: 加锁后复制原数组并扩容1位,在新数组末尾添加元素,最后替换底层数组引用。体现了"写时复制"的核心思想。

3.2 remove()

源代码如下:

public E remove(int index) {final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();int len = elements.length;E oldValue = get(elements, index);int numMoved = len - index - 1;if (numMoved == 0)setArray(Arrays.copyOf(elements, len - 1));else {Object[] newElements = new Object[len - 1];System.arraycopy(elements, 0, newElements, 0, index);System.arraycopy(elements, index + 1, newElements, index,numMoved);setArray(newElements);}return oldValue;} finally {lock.unlock();}}

实现复述:加锁后创建缩容1位的新数组,分两种情况处理:如果是最后一位元素直接截断,否则删除中间元素并分两段复制到新数组中。

3.3 set()

源代码如下:

public E set(int index, E element) {final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();E oldValue = get(elements, index);if (oldValue != element) {int len = elements.length;Object[] newElements = Arrays.copyOf(elements, len);newElements[index] = element;setArray(newElements);} else {// Not quite a no-op; ensures volatile write semanticssetArray(elements);}return oldValue;} finally {lock.unlock();}}

实现概述: 加锁后先比较新旧值,如果不同则复制整个数组并修改指定位置的元素,相同时也要调用setArray()确保数组中的内容是最新的。

3.4 get()

源代码如下:

private E get(Object[] a, int index) {return (E) a[index];
}

实现概述: 无锁操作,直接从volatile数组中获取指定位置的元素,保证了读操作的高性能。


http://www.dtcms.com/a/284443.html

相关文章:

  • FRP配置( CentOS 7 上安装 FRP教程 )
  • MySql查询 值存在但查不到
  • 深度学习G3周:CGAN入门(生成手势图像)
  • 理解欧拉角:定义、转换与应用
  • HTTPS的工作原理及DNS的工作过程
  • 【LeetCode 热题 100】108. 将有序数组转换为二叉搜索树
  • SpringBoot使用ThreadLocal共享数据
  • 2021-07-21 VB窗体求范围质数(Excel复制工作簿)
  • Python 基础语法与数据类型(十三) - 实例方法、类方法、静态方法
  • 【测试100问】没有接口文档的情况下,如何做接口测试?
  • MinIO:开源对象存储解决方案的领先者
  • DiffPy-CMI详细安装教程
  • 【Vue进阶学习笔记】组合式API(Composition API)
  • Go 程序无法使用 /etc/resolv.conf 的 DNS 配置排查记录
  • React hooks——memo
  • 【软件开发】主流 AI 编码插件
  • 关于el-table异步获取数据渲染动态列数据赋值列数据渲染时title高度异常闪过问题
  • 深度解析:基于EasyX的C++黑白棋AI实现 | 算法核心+图形化实战
  • 数据呈现进阶:漏斗图与雷达图的实战指南
  • 基于Echarts的气象数据可视化网站系统的设计与实现(Python版)
  • Idea使用git不提示账号密码登录,而是输入token问题解决
  • 【解决方案】yakit流量转发到mitmproxy
  • 浅谈 awk 中管道的用法
  • zynq mpsoc switch级联ssd高速存储方案
  • 贴吧项目总结二
  • mysql——搭建MGR集群
  • CommonJS 功能介绍
  • 基于dcmtk的dicom工具 第二章 图像接受StoreSCP(2)
  • Python Day16
  • Java行为型模式---备忘录模式