java并发编程之 CopyOnWriteArrayList

【java】java 并发编程 CopyOnWriteArrayList 文章目录1.介绍2. 原理和数据结构2.1 线程安全2.2 结构3. 函数列表4. 源码分析4.1. 创建4.2. 添加4.3. 获取4.4 删除4.5. 遍历5. 示例M.扩展阅读 1.介绍 它相当于线程安全的ArrayList。和ArrayList一样,它是个可变数组;但是和ArrayList不同的时,它具有以下特性: 它最适合于具有以下特征的应用程序:List 大小通常保持很小,只读操作远多于可变操作,需要在遍历期间防止线程间的冲突。 它是线程安全的。 因为通常需要复制整个基础数组,所以 阅读详情

我们都知道在java容器中ArrayList是线程不安全的,而vector是线程安全的。那么针对线程安全和不安全来说,这两个容器应该是够用了,为什么还要出现一个CopyOnWriteArrayList这个容器呢?CopyOnWriteArrayList是线程安全的,那么它较vector有哪些优势呢?

看一下vector的add和get源码

/**
     * Appends the specified element to the end of this Vector.
     *
     * @param e element to be appended to this Vector
     * @return {@code true} (as specified by {@link Collection#add})
     * @since 1.2
     */
    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }


/**
     * Returns the element at the specified position in this Vector.
     *
     * @param index index of the element to return
     * @return object at the specified index
     * @throws ArrayIndexOutOfBoundsException if the index is out of range
     *            ({@code index < 0 || index >= size()})
     * @since 1.2
     */
    public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    }

可以看到对于vector的add和get方法都被synchronize修饰了,这就说明了当我在获取数据的时候,其他线程也是不能获取的,所有的读和写都会被阻塞。

再来看CopyOnWriteArrayList中的源码

/**
     * Inserts the specified element at the specified position in this
     * list. Shifts the element currently at that position (if any) and
     * any subsequent elements to the right (adds one to their indices).
     *
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public void add(int index, E element) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            if (index > len || index < 0)
                throw new IndexOutOfBoundsException("Index: "+index+
                                                    ", Size: "+len);
            Object[] newElements;
            int numMoved = len - index;
            if (numMoved == 0)
                newElements = Arrays.copyOf(elements, len + 1);
            else {
                newElements = new Object[len + 1];
                System.arraycopy(elements, 0, newElements, 0, index);
                System.arraycopy(elements, index, newElements, index + 1,
                                 numMoved);
            }
            newElements[index] = element;
            setArray(newElements);
        } finally {
            lock.unlock();
        }
    }

简单的概括就是,在添加数据的时候,系统会复制一个新的list然后添加的时候往新的array添加,当然这个新的list是lock确保线程安全的。

等新的list操作完成之后,再把旧的list引用的地址指向它即可。但是旧的list是没有加锁的,所以读的操作是不会阻塞的。

copyOnWriterArrayList通过消耗空间的方式来提高系统的并发性,但是这样浪费了空间,容易造成minor Gc ,严重的话会造成full gc。所以要根据情况来选择使用。

Java并发编程中并发容器ConcurrentHashMap和CopyOnWriteArrayList JDK 5 中加入的 ConcurrentHashMap:用来替代同步且基于散列的Map CopyOnWriteArrayList:用于在遍历操作为主要操作的情况下替代同步的List ConcurrentMap:“若没有则添加”、替换、有条件删除 Queue:用来临时保存一组待处理的元素,Queue上的操作不会阻塞,如果队列为空,那么获取元素的操作将返回空值。虽然可以用List来模拟Que 阅读详情

相关推荐

PX4无人机offboard开发之旅

(慢慢更)无人机OFFBOARD开发

InTereSTingHE的博客 1078

CopyOnWriterArrayList 详解

在 ArrayList 的类注释上,JDK 就提醒了我们,如果要把 ArrayList 作为共享变量的话,是线程不安全的,推荐我们自己加锁或者使用 Collections.synchronizedList 方法,其实 JDK 还提供了另外一种线程安全的 List,叫做 CopyOnWriteArrayList。......

GeGe&YoYo的博客 1万+

Cadence Sigrity PowerDC实战:如何用PCB电热混合仿真解决散热难题(附详细配置步骤)

本文详细介绍了如何利用Cadence Sigrity PowerDC进行PCB电热混合仿真,以解决高功率密度设计中的散热难题。文章通过解析电热耦合原理,并附上详细的配置步骤与实战技巧,指导硬件工程师同步优化电气性能与热管理,从而在设计源头提升产品可靠性与效率。

weixin_29292535的博客 198

并发编程一:CopyOnWriteArrayList

除了加锁外,其实还有一种方式可以防止并发修改异常,这就是将读写分离技术(不是数据库上的)。 先回顾一下一个常识: 1、JAVA中“=”操作只是将引用和某个对象关联,假如同时有一个线程将引用指向另外一个对象,一个线程获取这个引用指向的对象,那么他们之间不会发生ConcurrentModificationException,他们是在虚拟机层面阻塞的,而且速度非常快,几乎不需要CPU时间。 2

keep_moving_cqu的专栏 1621

多周期路径及set_multicycle_path详解

默认情况下,每条路径都被定义为单周期,即源触发器在时钟的任一边沿启动(launch)的数据都应该由目的触发器在时钟的下一上升沿捕获(capture)。 有的设计需要在数据被捕获前提供一些额外的周期,这类路径被称为多周期路径。 一、set_multicycle_path命令 命令格式如下: set_multicycle_path .........

Jackiezhang1993的博客 4万+

不止是打字机效果:手把手教你用SpannableStringBuilder打造Android富文本AI对话界面

本文详细介绍了如何使用SpannableStringBuilder在Android平台上构建专业级AI对话界面,涵盖流式文本处理、富文本解析、交互优化等核心技术。通过实战代码示例,帮助开发者实现类似DeepSeek的AI产品交互效果,提升用户体验和应用专业度。

weixin_28358083的博客 198

Java并发编程系列学习_并发容器CopyOnWriteArrayList

一、ArrayList线程不安全的原因 ArrayList很常用,但是该集合并不是一个线程安全的集合,首先我们来看下这个集合的内部构造成员: public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java....

JingHaiRoad Coder 283

Pyhon在振动信号处理中的高级应用(一):振动信号特征(时域、频域)提取

文章目录一、概述二、算法原理2.1 时域统计特征三、python代码实现 一、概述 二、算法原理   这里我们借鉴西安交通大学机械学院雷教授的论文《Fault diagnosis of rotating machinery based on multiple ANFIS combination with GAs》相关研究成果。雷教授在论文中共列举了4类共24种振动信号的时域和频域特征。 2.1 时域统计特征 p1=∑n=1Nx(n)NP2=∑n=1N(x(n)−p1)2N−1p3=(∑n=1N∣x(n)∣N

白银时代的博客 1万+

CopyOnWriterArrayList原理

CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

yzx3105的博客 635

uniapp - 最新实现hbuilder项目运行到ios基座或苹果ios真机设备详细教程,如何在ios苹果手机上真机运行测试,IOS自定义基座在线打包调试(uniapp项目如何在苹果手机上运行调试)

uni-app,苹果,app,ios,设备,自定义基座,运行app到苹果手机,mac电脑,Xcode,hbuilderX,运行ios基座调试Uniapp,无需打包,苹果证书,ipa,运行失败,报错,无法启动,连接失败,出错,详细教程,如何解决这个问题,怎么办,申请iOS证书,运行项目到iOS基座,打包ios自定义基座,在iOS真机上运行,新手小白,超级详细的教程,dcloud如何苹果ios系统真机测试,调试基座失败,真机调试ios app,App基座安装后无法打开问题,真机运行时检测不到手机的问题或者基座安

✅ 精选推荐文章 1万+

药物对接仿真软件:HADDOCK_(3).分子对接基本原理

分子对接(Molecular Docking)是计算化学和结构生物学中的一种重要技术,用于预测小分子(如药物分子)与大分子(如蛋白质)之间的相互作用模式和结合亲和力。这一技术在药物设计和开发中具有广泛的应用,尤其是在寻找和优化潜在的药物候选物方面。本节将详细介绍分子对接的基本原理,包括其理论基础、计算方法和应用。

kkchenjj的博客 1170

java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList 解决方法

控制台报错如下 org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException:java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList 报错代码 //获取一个字符串数组 String[] idsArr= s.sp.

JavaWebEngineer的博客 1万+

【架构】-- StarRocks 和 Doris 介绍与选型建议

查询性能 | ✅ 高性能,支持向量化执行和 CBO 优化器 | ✅ 高性能,优化的查询引擎 |- **实时性要求高**:如果业务对数据的实时性要求较高,建议选择 **StarRocks**,其在实时数据处理和低延迟查询方面表现优越。- **复杂查询需求**:对于需要处理复杂多表关联查询的场景,两者均可胜任,需根据具体性能测试结果进行选择。

欢迎来到我的博客,一起探索代码里的世界! 1834

Java并发编程—CopyOnWriteArrayList

1 概述 JUC并发包中只提供了一个并发list就是CopyOnWriteList,是线程安全的(内部有一个独占锁ReetrantLock),采用的是写时复制的策略。整体的类图结构如下图所示。 下面从构造方法,增删改查与迭代器遍历来对该类进行一些详细的介绍。 2 构造方法 该类共有三个构造方法,一个无参构造,一个传入一个集合的有参构造,一个是传入一个泛型数组的有参构造 public CopyOnWriteArrayList() //无参构造器在内部创建了一个大小为0的Object数组 p..

wait2023的博客 509

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

深入剖析Java并发编程核心原理:从ConcurrentHashMap到CopyOnWriteArrayList

在多核处理器成为主流的今天,并发编程已成为提升系统性能的关键手段。竞态条件内存可见性问题以及指令重排序带来的不确定性。这些问题直接催生了Java内存模型(JMM)的诞生,通过happens-before规则、volatile语义和同步机制构建起线程安全的基础框架。以经典的i++操作为例,这个看似简单的语句实际上包含读取、计算、写入三个步骤,在多线程环境下可能因线程切换导致计算结果丢失。传统的关键字虽然能解决这些问题,但粗粒度的锁机制往往成为性能瓶颈。此时,并发容器。

zuiyuelong的博客 707

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Java并发编程:并发容器之CopyOnWriteArrayList

来源: http://www.cnblogs.com/dolphin0520/p/3938914.html

zhaoyang10的专栏 159

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Java并发编程之CopyOnWriteArrayList

什么是CopyOnWrite Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。 什么是CopyOnWrite容器 CopyOnWrite容器即写时复制的容器。当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容...

Geffin的博客 409

Java并发编程:并发容器之CopyOnWriteArrayList(转载)

CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

m0_46225088的博客 107

Java并发编程 - JUC并发集合(CopyOnWriteArrayList、CopyOnWriteArraySet)

和是 Java 并发编程中非常有用的线程安全集合类。它们通过复制整个数组并在副本上进行修改来保证线程安全,特别适用于读多写少的场景。然而,由于它们在写操作时创建数组副本,因此在写操作频繁的场景下可能会导致较高的内存消耗。在实际开发中,应根据具体的应用场景选择合适的并发集合类。

qq_33240556的博客 547

Java并发编程之CopyOnWriteArraylist

Java并发编程之CopyOnWriteArraylist 引言: Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。CopyOnWrite容器非常有用,可以在非

zdl_csdn的博客 280

Java 并发编程之 CopyOnWriteArrayList

简单说就是读写分离,读不加锁,增删改时加锁复制,线程安全; 写的效率比较低,相对Vector类读写都加锁,CopyOnWriteArrayList读的效率更高,适合读多写少,并且不要求实时一致性的使用场景。 方法有: public boolean add(E e),public void add(int index, E element) public E set(int index, E element),public E get(int index) public E remove(int .

风香枫 318

Java并发编程六之CopyOnWriteArrayList

阅读目录CopyOnWriteArrayList是什么为什么使用CopyOnWriteArrayListCopyOnWriteArrayList实现 CopyOnWriteArrayList是什么 CopyOnWriteArrayList 是jdk1.5以后并发包中提供的一种并发容器,写操作通过创建底层数组的新副本来实现,是一种读写分离的并发策略,我们也成为“写时复制容器”,类似的容器还有 CopyOnWriteArraySet。 为什么使用CopyOnWriteArrayList 众所周知,集合框架

yangyanping20108的博客 373
上一篇: JVM GC垃圾回收器详解
下一篇: TCP连续ARQ协议和滑动窗口协议
CallMeJiaGu
博客等级 码龄12年 149粉丝 99原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值