Java线程安全集合类

Java线程安全集合类全面解析

目录

  1. 并发集合概述
  2. List线程安全实现
  3. Set线程安全实现
  4. Map线程安全实现
  5. Queue线程安全实现
  6. 总结

并发集合概述

Java提供了多种线程安全的集合类,主要分为两大类:

  1. 传统同步集合:通过synchronized关键字实现线程安全
  2. 并发集合:采用更高效的并发控制机制(如CAS、分段锁等)
Java集合
线程安全集合
同步集合
并发集合
Collections.synchronizedXXX
CopyOnWriteArrayList
ConcurrentHashMap
ConcurrentLinkedQueue

List线程安全实现

1. Vector

  • 底层结构:动态数组(类似ArrayList)
  • 线程安全机制:所有方法使用synchronized修饰
  • 缺点:性能差(全表锁)
  • 使用场景:已过时,不推荐使用
// 示例代码
Vector<String> vector = new Vector<>();
vector.add("item"); // 同步方法

2. Collections.synchronizedList

  • 底层结构:包装普通List
  • 线程安全机制:所有方法通过同步块加锁
  • 优点:兼容所有List实现
  • 缺点:迭代时需要手动同步
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 遍历时需要手动同步
synchronized(syncList) {for(String item : syncList) {// 处理逻辑}
}

3. CopyOnWriteArrayList

  • 底层结构:volatile数组+写时复制
  • 线程安全机制
    • 读操作:无锁访问数组快照
    • 写操作:ReentrantLock+数组复制
  • 优点:读性能极高
  • 缺点:写性能差,内存占用高
  • 使用场景:读多写少(事件监听器、配置管理)
CopyOnWriteArrayList<String> cowList = new CopyOnWriteArrayList<>();
cowList.add("item"); // 加锁复制数组
String item = cowList.get(0); // 无锁读取

Set线程安全实现

1. Collections.synchronizedSet

  • 底层结构:包装普通Set
  • 线程安全机制:全方法同步
  • 缺点:性能较差

2. CopyOnWriteArraySet

  • 底层结构:基于CopyOnWriteArrayList
  • 线程安全机制:同CopyOnWriteArrayList
  • 使用场景:小型读多写少集合

3. ConcurrentSkipListSet

  • 底层结构:跳表(SkipList)
  • 线程安全机制:CAS+自旋
  • 优点:有序且并发性能好
  • 使用场景:需要有序的高并发Set
ConcurrentSkipListSet<String> set = new ConcurrentSkipListSet<>();
set.add("item"); // 线程安全

Map线程安全实现

1. Hashtable

  • 底层结构:数组+链表
  • 线程安全机制:全方法同步
  • 缺点:性能差(全表锁)
  • 使用场景:已过时,不推荐使用

2. Collections.synchronizedMap

  • 底层结构:包装普通Map
  • 线程安全机制:全方法同步
  • 缺点:迭代时需要手动同步

3. ConcurrentHashMap

  • 底层结构
    • JDK7:分段锁(Segment)
    • JDK8:数组+链表/红黑树+CAS+synchronized
  • 线程安全机制
    • 读操作:无锁(volatile读)
    • 写操作:CAS+同步块(锁住链表头节点)
  • 优点:高并发性能优异
  • 使用场景:高并发键值存储(缓存、计数器等)
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key", 1); // 分段锁/CAS
int value = map.get("key"); // 无锁读取

Queue线程安全实现

1. ConcurrentLinkedQueue

  • 底层结构:链表+CAS
  • 线程安全机制:无锁算法(CAS)
  • 优点:高并发性能好
  • 缺点:size()方法开销大
  • 使用场景:高并发生产者消费者
ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
queue.offer("item"); // CAS操作
String item = queue.poll(); // CAS操作

2. BlockingQueue实现类

实现类特点使用场景
ArrayBlockingQueue有界数组+ReentrantLock固定大小队列
LinkedBlockingQueue可选有界链表+双锁通用阻塞队列
PriorityBlockingQueue优先级堆+锁优先级任务调度
SynchronousQueue直接传递+双栈线程池任务传递
DelayQueue优先级堆+锁延时任务调度
BlockingQueue<String> queue = new ArrayBlockingQueue<>(100);
queue.put("item"); // 阻塞写入
String item = queue.take(); // 阻塞取出

总结与选型建议

性能对比

集合类型读性能写性能一致性
同步集合
CopyOnWrite极好
ConcurrentHashMap极好
CAS无锁队列极好极好

选型指南

  1. List场景

    • 读多写少 → CopyOnWriteArrayList
    • 读写均衡 → Collections.synchronizedList
  2. Map场景

    • 高并发 → ConcurrentHashMap
    • 需要排序 → ConcurrentSkipListMap
  3. Queue场景

    • 无界非阻塞 → ConcurrentLinkedQueue
    • 有界阻塞 → ArrayBlockingQueue
    • 延时任务 → DelayQueue
  4. Set场景

    • 小型集合 → CopyOnWriteArraySet
    • 大型并发 → ConcurrentSkipListSet

最佳实践

  1. 优先考虑并发集合而非同步集合
  2. 根据读写比例选择合适实现
  3. 注意迭代时的线程安全问题
  4. 高并发环境避免使用size()、containsAll()等方法
// 线程安全集合使用示例
ConcurrentHashMap<String, User> cache = new ConcurrentHashMap<>();
CopyOnWriteArrayList<EventListener> listeners = new CopyOnWriteArrayList<>();
BlockingQueue<Task> taskQueue = new LinkedBlockingQueue<>(1000);

工作中我们需要根据实际情况来选择线程安全集合,这样可以在保证线程安全的同时获得最佳性能表现。

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

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

相关文章

汇川变频器MD600S-4T-5R5为什么要搭配GRJ9000S-10-T滤波器?

一、变频器的工作原理与电磁干扰 汇川MD600S-4T-5R5变频器是一款紧凑型高性能变频器&#xff0c;适用于三相380V-480V电网&#xff0c;额定电流5.5A&#xff0c;支持矢量控制和多种编码器接口&#xff0c;适用于需要高精度速度和转矩控制的场景&#xff0c;如机器人、电梯、纺…

数学运算在 OpenCV 中的核心作用与视觉效果演示

在计算机视觉中&#xff0c;图像不仅仅是我们肉眼所见的内容&#xff0c;它其实是由数值矩阵组成的“数据”。而在 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;中&#xff0c;正是数学运算赋予了图像处理无限的可能——从基本的滤波、增强到复杂的特征…

【快速预览经典深度学习模型:CNN、RNN、LSTM、Transformer、ViT全解析!】

&#x1f680;快速预览经典深度学习模型&#xff1a;CNN、RNN、LSTM、Transformer、ViT全解析&#xff01; &#x1f4cc;你是否还在被深度学习模型名词搞混&#xff1f;本文带你用最短时间掌握五大经典模型的核心概念和应用场景&#xff0c;助你打通NLP与CV的任督二脉&#xf…

springboot mysql/mariadb迁移成oceanbase

前言&#xff1a;项目架构为 springbootmybatis-plusmysql 1.部署oceanbase服务 2.springboot项目引入oceanbase依赖&#xff08;即ob驱动&#xff09; ps&#xff1a;删除原有的mysql/mariadb依赖 <dependency> <groupId>com.oceanbase</groupId> …

电网“逆流”怎么办?如何实现分布式光伏发电全部自发自用?

2024年10月9日&#xff0c;国家能源局综合司发布了《分布式光伏发电开发建设管理办法&#xff08;征求意见稿&#xff09;》&#xff0c;意见稿规定了户用分布式光伏、一般工商业分布式光伏以及大型工商业分布式光伏的发电上网模式&#xff0c;当选择全部自发自用模式时&#x…

C语言之编译器集合

C语言有多种不同的编译器&#xff0c;以下是常见的编译工具及其特点&#xff1a; 一、主流C语言编译器 GCC&#xff08;GNU Compiler Collection&#xff09; 特点&#xff1a;开源、跨平台&#xff0c;支持多种语言&#xff08;C、C、Fortran 等&#xff09;。 使用场景&…

负载均衡将https请求转发后端http服务报错:The plain HTTP request was sent to HTTPS port

https请求报错&#xff1a;The plain HTTP request was sent to HTTPS port 示例背景描述&#xff1a; www.test.com:11001服务需要对互联网使用https提供服务后端java服务不支持https请求&#xff0c;且后端程序无法修改&#xff0c;仅支持http请求 问题描述&#xff1a; 因…

(3)Playwright自动化-3-离线搭建playwright环境

1.简介 如果是在公司局域网办公&#xff0c;或者公司为了安全对网络管控比较严格这种情况下如何搭建环境&#xff0c;我们简单来看看 &#xff08;第一种情况及解决办法&#xff1a;带要搭建环境的电脑到有网的地方在线安装即可。 &#xff08;第二种情况及解决办法&#xf…

【Fiddler抓取手机数据包】

Fiddler抓取手机数据包的配置方法 确保电脑和手机在同一局域网 电脑和手机需连接同一Wi-Fi网络。可通过电脑命令行输入ipconfig查看电脑的本地IP地址&#xff08;IPv4地址&#xff09;&#xff0c;手机需能ping通该IP。 配置Fiddler允许远程连接 打开Fiddler&#xff0c;进入…

PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的区别

python容易编辑&#xff0c;因此用pyrx代替rxjava3做演示会比较快捷。 pyrx安装命令&#xff1a; pip install rx 一、Subject&#xff08;相当于 RxJava 的 PublishSubject&#xff09; PublishSubject PublishSubject 将对观察者发送订阅后产生的元素&#xff0c;而在订阅前…

BLE中心与外围设备MTU协商过程详解

一、MTU基础概念​​ 1. ​​MTU定义​​ ​​最大传输单元&#xff08;MTU&#xff09;​​ 指单次数据传输中允许的最大字节数&#xff0c;包含协议头部&#xff08;3字节&#xff09;和有效载荷&#xff08;最多517字节&#xff09;。BLE默认MTU为​​23字节​​&a…

【华为云Astro-服务编排】服务编排使用全攻略

目录 概述 为什么使用服务编排 服务编排基本能力 拖拉拽式编排流程 逻辑处理 对象处理 服务单元组合脚本、原生服务、BO、第三方服务 服务编排与模块间调用关系 脚本 对象 标准页面 BPM API接口 BO 连接器 如何创建服务编排 创建服务编排 如何开发服务编排 服…

centos实现SSH远程登录

1. 生成SSH密钥对 首先&#xff0c;你需要在客户端机器上生成一个SSH密钥对。打开终端&#xff0c;执行以下命令 ssh-keygen 或ssh-keygen -t rsa -b 2048&#xff08;效果相同&#xff09; 按照提示操作&#xff0c;可以按回车键接受默认的文件名&#xff08;通常是~/.ssh/id_…

定制开发开源AI智能名片S2B2C商城小程序在无界零售中的应用与行业智能升级示范研究

摘要&#xff1a;本文聚焦无界零售背景下京东从零售产品提供者向零售基础设施提供者的转变&#xff0c;探讨定制开发开源AI智能名片S2B2C商城小程序在这一转变中的应用。通过分析该小程序在商业运营成本降低、效率提升、用户体验优化等方面的作用&#xff0c;以及其与京东AI和冯…

ZooKeeper 安装教程(Windows + Linux 双平台)

ZooKeeper 安装教程(Windows + Linux 双平台) Zookeeper 和 Kafka 版本与 JDK 要求 一、安装前准备 系统要求 Java 环境(JDK17+)开放端口:2181(客户端),2888(集群通信),3888(选举)安装 Java Linux(Ubuntu/CentOS) # Ubuntu

【Git系列】如何同步原始仓库的更新到你的fork仓库?

&#x1f389;&#x1f389;&#x1f389;欢迎来到我们的博客&#xff01;无论您是第一次访问&#xff0c;还是我们的老朋友&#xff0c;我们都由衷地感谢您的到来。无论您是来寻找灵感、获取知识&#xff0c;还是单纯地享受阅读的乐趣&#xff0c;我们都希望您能在这里找到属于…

Could not obtain transaction-synchronized Session for current thread

背景 写了一个函数&#xff0c;分别支持手动调用和定时任务调用。 测试的时候一直用手动点击按钮触发函数&#xff0c;功能可用 等到了测试定时任务的时候&#xff0c;后台报错 Could not obtain transaction-synchronized Session for current thread错误分析 事务管理不匹…

linux nm/objdump/readelf/addr2line命令详解

我们在开发过程中通过需要反汇编查看问题&#xff0c;那么我们这里使用rk3568开发板来举例nm/objdump/readelf/addr2line 分析动态库和可执行文件以及.o文件。 1&#xff0c;我们举例nm/objdump/readelf/addr2line解析linux 内核文件vmlinux &#xff08;1&#xff09;,addr2…

C++自定义简单的内存池

内存池简述 在C的STL的容器中的容器如vector、deque等用的默认分配器(allocator)都是从直接从系统的堆中申请内存&#xff0c;用一点申请一点&#xff0c;效率极低。这就是设计内存池的意义&#xff0c;所谓内存池&#xff0c;就是一次性向系统申请一大片内存&#xff08;预分…

【极客日常】分享go开发中wire和interface配合的一些经验

在先前一篇文章中&#xff0c;笔者给大家提到了go语言后端编程可以用wire依赖注入模块去简化单例服务的初始化&#xff0c;同时也可以解决服务单例之间复杂依赖的问题。但实事求是来讲&#xff0c;用wire也是有一些学习成本的&#xff0c;wire在帮助解决复杂依赖的问题同时&…