本文介绍: CopyOnWriteArrayList 是 Java 中的一个线程安全集合类。它实现了 List 接口,并且能够在高并发环境下提供一致的读写操作。本章节通过源码解读带你了解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 时,需要考虑下自己的数据量以及读写的频次。

原文地址:https://blog.csdn.net/weixin_65777087/article/details/134676132

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_4741.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注