CopyOnWriteArrayList技术探究

简介: CopyOnWriteArrayList 是java.util.concurrent的并发类,线程安全,遵循写时复制的原则(CopyOnWrite)。通过“写入时复制”(Copy-On-Write, COW)的策略来保证集合的线程安全,适用于读多写少的并发场景。

工作原理

CopyOnWriteArrayList 是java.util.concurrent的并发类,线程安全,遵循写时复制的原则(CopyOnWrite)。通过“写入时复制”(Copy-On-Write, COW)的策略来保证集合的线程安全,适用于读多写少的并发场景。

CopyOnWriteArrayList 在每次修改操作时(如添加、删除、设置等),都会通过复制底层数组来创建一个新的数组,并在这个新数组上进行修改,然后将原数组的引用指向这个新数组。这样,在修改过程中,迭代器和其他分割器(spliterator)可以继续安全地遍历原数组,因为它们不会受到修改操作的影响。

优点

  1. 线程安全:通过内部机制保证了线程安全,无需外部同步。
  2. 读操作性能高:读操作不会加锁,且多个读操作可以并发执行,因此读操作的性能非常高。

缺点

  1. 内存占用高:每次修改操作都需要复制整个底层数组,这会导致大量的内存占用,特别是在数组较大且修改频繁时。
  2. 写操作性能低:写操作(添加、删除、设置等)涉及数组的复制,因此写操作相对较慢,且写操作的性能会随着数组容量的增加而下降。

使用场景

  • 读多写少的并发场景。
  • 遍历操作远多于修改操作的场景。
  • 在需要线程安全的列表,但又不想因为使用 Vector 而导致性能下降时。

示例代码

import java.util.concurrent.CopyOnWriteArrayList;  
  
public class CopyOnWriteArrayListExample {  
    public static void main(String[] args) {  
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();  
  
        // 线程1添加元素  
        Thread t1 = new Thread(() -> {  
            for (int i = 0; i < 10; i++) {  
                list.add("Element " + i);  
                try {  
                    Thread.sleep(100); // 模拟耗时操作  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        });  
  
        // 线程2遍历元素  
        Thread t2 = new Thread(() -> {  
            for (String s : list) {  
                System.out.println(s);  
            }  
        });  
  
        t1.start();  
        t2.start();  
  
        try {  
            t1.join();  
            t2.join();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
}

image.gif

总结

CopyOnWriteArrayList的优势在于可以保证线程安全的同时,不阻塞读操作,但是这仅限于读多写少的情况,在写多读少的情况下,或者写入的对象占用内容较大时,不建议使用。

相关文章
|
存储 关系型数据库 MySQL
MySQL - 索引类型详解
MySQL - 索引类型详解
493 0
|
Unix Linux Shell
FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库
在Linux环境下交叉编译Android所需的FFmpeg so库,首先下载`android-ndk-r21e`,然后解压。接着,上传FFmpeg及相关库(如x264、freetype、lame)源码,修改相关sh文件,将`SYSTEM=windows-x86_64`改为`SYSTEM=linux-x86_64`并删除回车符。对x264的configure文件进行修改,然后编译x264。同样编译其他第三方库。设置环境变量`PKG_CONFIG_PATH`,最后在FFmpeg源码目录执行配置、编译和安装命令,生成的so文件复制到App工程指定目录。
715 9
FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库
|
人工智能 小程序
【一步步开发AI运动小程序】十五、AI运动识别中,如何判断人体站位的远近?
【云智AI运动识别小程序插件】提供人体、运动及姿态检测的AI能力,无需后台支持,具有快速、体验好、易集成等特点。本文介绍如何利用插件判断人体与摄像头的远近,确保人体图像在帧内的比例适中,以优化识别效果。通过`whole`检测规则,分别实现人体过近和过远的判断,并给出相应示例代码。
|
安全 Java UED
掌握SpringBoot单点登录精髓,单点登录是一种身份认证机制
【8月更文挑战第31天】单点登录(Single Sign-On,简称SSO)是一种身份认证机制,它允许用户只需在多个相互信任的应用系统中登录一次,即可访问所有系统,而无需重复输入用户名和密码。在微服务架构日益盛行的今天,SSO成为提升用户体验和系统安全性的重要手段。本文将详细介绍如何在SpringBoot中实现SSO,并附上示例代码。
437 0
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
379 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
Web App开发 5G Linux
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
一年一度的毕业季来临,计算机专业的毕业设计尤为重要,不仅关乎学业评价还积累实战经验。选择紧跟5G技术趋势的音视频APP作为课题极具吸引力。这里推荐三类应用:一是融合WebRTC技术实现视频通话的即时通信APP;二是具备在线直播功能的短视频分享平台,涉及RTMP/SRT等直播技术;三是具有自定义动画特效及卡拉OK歌词字幕功能的视频剪辑工具。这些项目不仅技术含量高,也符合市场需求,是毕业设计的理想选择。
424 6
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
|
JavaScript 前端开发 Java
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
IT寒冬使APP开发门槛提升,安卓程序员需转型。选项包括:深化Android开发,跟进Google新技术如Kotlin、Jetpack、Flutter及Compose;研究Android底层框架,掌握AOSP;转型Java后端开发,学习Spring Boot等框架;拓展大前端技能,掌握JavaScript、Node.js、Vue.js及特定框架如微信小程序、HarmonyOS;或转向C/C++底层开发,通过音视频项目如FFmpeg积累经验。每条路径都有相应的书籍和技术栈推荐,助你顺利过渡。
513 3
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
|
Java 编译器
Java“操作符 ... 不能应用于 x”解决
当Java编译器报错“操作符 ... 不能应用于 x”时,通常是因为你尝试对不支持该操作符的数据类型执行了操作。解决方法包括:确保数据类型兼容、使用正确的类型转换或选择合适的方法。检查代码中的变量类型和操作符使用是否正确。
264 4
|
人工智能 小程序
【一步步开发AI运动小程序】七、进行运动计时、计数
随着AI技术的发展,阿里体育推出的“乐动力”、“天天跳绳”等APP,使云上运动会、AI体育指导等概念备受关注。本文将引导您从零开始,利用“云智AI运动识别小程序插件”,在小程序中实现类似功能。通过插件的`sports`和`calc`命名空间,可轻松实现运动检测、计时计数等功能。示例代码展示了如何创建并使用俯卧撑运动分析器,以及如何通过摄像头捕获图像进行人体识别和运动分析。敬请期待后续关于姿态分析的内容。
|
编解码 算法 图形学
同一路RTSP|RTMP流如何同时回调YUV和RGB数据实现渲染和算法分析
我们播放RTSP|RTMP流,如果需要同时做渲染和算法分析的话,特别是渲染在上层实现(比如Unity),算法是python这种情况,拉两路流,更耗费带宽和性能,拉一路流,同时回调YUV和RGB数据也可以,但是更灵活的是本文提到的按需转算法期望的RGB数据,然后做算法处理
290 2

热门文章

最新文章

下一篇
开通oss服务