多线程开发中List的使用

news2025/4/11 15:38:04

由于ArrayList在多线程高并发情况下是不安全的,因此要慎用,那么此时如果涉及到集合操作,应该怎么选:

方案一:Vector:

特点:通过给所有方法都用 synchronized 修饰从而保证线程安全,

缺点:CopyOnWriteArrayList

  • 高并发场景下性能较差(锁竞争严重)。

  • 即使单线程环境也会因同步开销影响性能。

总结:不建议使用。

方案二:Collections.synchronizedList

特点:低并发读写,简单封装 ArrayList,所有方法加锁。

缺点:高并必情况下性能不如CopyOnWriteArrayList

使用示例:

List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 复合操作仍需外部同步
synchronized (syncList) {
    if (!syncList.contains("value")) {
        syncList.add("value");
    }
}

方案三:CopyOnWriteArrayList

特点:

    1.读操作:无锁,直接访问底层数组;

            2.写操作:复制新数组,修改后替换旧数组(适合 读多写极少 的场景)。

缺点:

           1.写操作开销大(需复制数组)。

           2.数据一致性弱:读取的是某一时刻的快照,可能读到旧数据。

使用示例:

// 示例:事件监听器列表
private final List<Listener> listeners = new CopyOnWriteArrayList<>();

 拓展:

CopyOnwriteArrayList通过JUC包下的lock来实现线程间的同步的, 可实现了读读操作和读写操作不互斥。
它是怎么实现读写不互斥的呢?
在面临写操作的时候,CopyOnwriteArrayList会先复制原来的数组并且在新数组上进行修改,最后再将原数组覆盖。如果写操作过程中发生了线程切换。并且切换到读线程,因为此时数组并未发生覆盖,读操作读取的还是原数组。另外,数组定义private transient volatile Object[] array,其中采用volatile修饰,保证内存可见性,读取线程可以马上知道这个修改。也就是说当读写并发时读操作是在旧数组中读到的旧值(一致性弱)。

方案四:ConcurrentLinkedQueue

特点:

  1.高并发队列操作(如任务分发),基于 CAS 无锁实现。

      2.线程安全:多线程并发添加无需额外同步。

      3. 无阻塞:操作立即返回,不会因锁竞争导致线程挂起。

      4. 无容量限制:队列会动态扩展。

缺点

        1.不支持随机访问(非 List 接口实现)。

        2.弱一致性:迭代器创建后,其他线程的修改可能不会立即反映到遍历中。

        3.不支持 remove() 操作:尝试通过迭代器删除元素会抛出 UnsupportedOperationException

使用示例:

public class Main {
    public static void main(String[] args) {
        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
        
        // 添加元素(推荐使用 offer)
        queue.offer("A"); // 返回 true 表示成功
        queue.add("B");   // 与 offer 等效
       

        // 读取并移除头部元素
        String head1 = queue.poll(); // 返回 "A",队列变为 [B]
        System.out.println("Polled: " + head1);

        // 仅读取头部元素(不移除)
        String head2 = queue.peek(); // 返回 "B",队列仍为 [B]
        System.out.println("Peeked: " + head2);

        // 队列为空时
        queue.poll();               // 移除 "B",队列为空 []
        String head3 = queue.poll(); // 返回 null
        System.out.println("Polled empty: " + head3);
    }
}

方案五:ConcurrentHashMap 

特点:可实现高性能随机访问,需要设置KEY.

方案对比:

开发推荐

现代开发中更推荐 CopyOnWriteArrayList

  • 无锁读取:适合多核 CPU 环境,避免线程阻塞。

  • 代码简洁:无需手动同步,减少错误。

  • 安全迭代:迭代器不会抛出 ConcurrentModificationException

但需注意其 内存占用(写时复制会占用双倍空间)。

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

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

相关文章

使用 .NET 9 和 Azure 构建云原生应用程序:有什么新功能?

随着 .NET 9 推出一系列以云为中心的增强功能&#xff0c;开发人员拥有比以往更多的工具来在 Azure 上创建可扩展、高性能的云原生应用程序。让我们深入了解 .NET 9 中的一些出色功能&#xff0c;这些功能使构建、部署和优化云应用程序变得更加容易&#xff0c;并附有示例以帮助…

前端页面鼠标移动监控(鼠标运动、鼠标监控)鼠标防抖处理、mousemove、debounce()、事件停止触发、超时触发

文章目录 代码使用lodashjs库debounce函数做防抖处理&#xff08;只有鼠标移动停止并超过一定时间&#xff0c;才会触发&#xff09;手写防抖函数写法1写法2&#xff08;注意addEventListener监听函数的第二个参数接收的是一个函数&#xff0c;需要构造一个匿名返回函数&#x…

开源守护,智护童年——幼儿园未成年行为与安全智能监控系统

在孩子成长的每一步&#xff0c;安全始终是第一位的。幼儿园作为孩子们探索世界的起点&#xff0c;其安全管理的重要性不言而喻。然而&#xff0c;哭闹、打闹、意外跌倒&#xff0c;甚至外部隐患如陌生人逗留、内部管理疏漏等问题&#xff0c;常常让传统人工监控捉襟见肘。家长…

WinForm真入门(5)——控件的基类Control

控件的基类–Control 用于 Windows 窗体应用程序的控件都派生自 Control类并继承了许多通用成员,这些成员都是平时使用控件的过程最常用到的。无论要学习哪个控件的使用&#xff0c;都离不开这些基本成员&#xff0c;尤其是一些公共属性。由于 Conlrol 类规范了控件的基本特征…

《Linux内存管理:实验驱动的深度探索》【附录】【实验环境搭建 4】【Qemu 如何模拟numa架构】

我们在学习 linux 内核时&#xff0c;会涉及到很多 numa 的知识&#xff0c;那我们该如何在 qemu 中模拟这种情况&#xff0c;来配合我们的学习呢&#xff1f; 我们该如何模拟 如下的 numa 架构 Qemu 模拟 NUMA 架构 -M virt,gic-version3,virtualizationon,typevirt \ -cp…

【YOLO系列(V5-V12)通用数据集-工程用车检测数据集】

YOLO格式的工程车检测数据集&#xff0c;适用于YOLOv5-v11所有版本&#xff0c;可以用于本科毕设、发paper、做课设等等&#xff0c;有需要的在这里获取&#xff1a; 【YOLO系列&#xff08;V5-V12&#xff09;通用数据集-工程用车检测数据集】 【工程车类型检测数据集】共2655…

卫星智能化健康管理#卫星工程系列

伴随我国航天业飞速发展&#xff0c;积累了大量的卫星试验数据&#xff0c;如何从海量、多源、多模态的卫星试验数据中挖掘分析出内部规律和潜在价值&#xff0c;构建卫星装备系统的全生命周期试验数据知识体系显得尤为迫切。卫星故障传统的诊断方法局限在门限层面&#xff0c;…

Neo4j操作数据库(Cypher语法)

Neo4j数据库操作语法 使用的数据库版本 (终端查询) >neo4j --version 2025.03.0批量上传数据 UNWIND [{name: Alice, age: 30},{name: Bob, age: 25} ] AS person CREATE (p:Person) SET p.name = person.name, p.age = person.age RETURN p;查询结点总数 MATCH (n) RETU…

[GN] Python3基本数据类型 -- 与C的差异

文章目录 前言Python3的基本数据类型6个标准的数据类型NumbersStringListtupleSetsDictionaries Python运算符逻辑 运算符成员运算符身份运算符 Python3 数字Python3 序列序列切片序列相加序列相乘序列相关内置函数 Python3 列表访问列表的值更新列表删除列表元素拼接列表嵌套列…

MSF上线到CS工具中 实战方案(可执行方案)

目录 实际案例背景 步骤详解 1. 获取低权限 Meterpreter 会话 1.1 使用 Metasploit 获取会话 2. 提权到 SYSTEM 权限 2.1 使用 getsystem 自动提权 2.2 如果 getsystem 失败&#xff1a;使用令牌冒充 (incognito 模块) 3. 上线到 Cobalt Strike 3.1 生成 Cobalt Strik…

IntelliJ IDEA 2020~2024 创建SpringBoot项目编辑报错: 程序包org.springframework.boot不存在

目录 前奏解决结尾 前奏 哈&#xff01;今天在处理我的SpringBoot项目时&#xff0c;突然遇到了一些让人摸不着头脑的错误提示&#xff1a; java: 程序包org.junit不存在 java: 程序包org.junit.runner不存在 java: 程序包org.springframework.boot.test.context不存在 java:…

基于DeepSeek、ChatGPT支持下的地质灾害风险评估、易发性分析、信息化建库及灾后重建

前言&#xff1a; 地质灾害是指全球地壳自然地质演化过程中&#xff0c;由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。在降水、地震等自然诱因的作用下&#xff0c;地质灾害在全球范围内频繁发生。我国不仅常见滑坡灾害&#xff0c;还…

Websoft9分享:在数字化转型中选择开源软件可能遇到的难题

引言&#xff1a;中小企业数字化转型的必由之路 全球94.57%的企业已采用开源软件&#xff08;数据来源&#xff1a;OpenLogic 2024报告)&#xff0c;开源生态估值达8.8万亿美元。中小企业通过开源软件构建EPR系统、企业官网、数据分析平台等&#xff0c;可节省80%软件采购成本。…

Windows修改hosts文件让向日癸软件联网

Windows修改hosts文件让向日癸软件联网 前言一、查看向日葵软件使用的网址及IP1.清除dns记录2.打开向日葵软件并将dns记录导出txt 二、修改Windows服务器的hosts文件1.winx选择Windows PowerShell(管理员)2.在Windows PowerShell中输入如下内容&#xff1a;3.在hosts文件最后添…

2021 CCF CSP-S2.括号序列

题目 4091. 括号序列 算法标签: 区间 d p dp dp 思路 区间 d p dp dp添加维表示形态 f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k], 对于每种形态考虑状态如何进行转移, 枚举的时候不能重复, 星号也要定义唯一的解析方式, 算法时间复杂度 O ( n 3 ) O(n ^ 3) O(n3) 代码 #…

Uni-app 项目 PDF 批注插件库在线版 API 示例教程

本文章介绍 Uni-app 项目中 PDF 批注插件库 ElasticPDF 在线版 API 示例教程&#xff0c;API 包含 ① 导出批注后PDF数据&#xff1b;② 导出纯批注 json 数据&#xff1b;③ 加载旧批注&#xff1b;④ 切换文档&#xff1b;⑤ 切换用户&#xff1b;⑥ 清空批注 等数据处理功能…

学透Spring Boot — 010. 单元测试和Spring Test

系列文章目录 这是CSDN postnull 博客《学透Spring Boot》系列的一篇&#xff0c;更多文章请移步&#xff1a;Postnull - 学透Spring Boot系列文章 文章目录 系列文章目录前言1. 基本概念UT 单元测试TDD 测试驱动开发UT测试框架Mock框架 3. Spring Test为什么要用Spring Test引…

TortoiseGit多账号切换配置

前言 之前配置好的都是&#xff0c;TortoiseGit与Gitee之间的提交&#xff0c;突然有需求要在GitHub上提交&#xff0c;于是在参考网上方案和TortoiseGit的帮助手册后&#xff0c;便有了此文。由于GitHub已经配置完成&#xff0c;所以下述以配置Gitee为例。因为之前是单账号使用…

3D 地图渲染-区域纹理图添加

引入-初始化地图&#xff08;关键代码&#xff09; // 初始化页面引入高德 webapi -- index.html 文件 <script src https://webapi.amap.com/maps?v2.0&key您申请的key值></script>// 添加地图容器 <div idcontainer ></div>// 地图初始化应该…

【Linux】条件变量封装类及环形队列的实现

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…