0

0

Java并发编程中的并发容器与线程安全

P粉602998670

P粉602998670

发布时间:2026-01-08 11:13:34

|

261人浏览过

|

来源于php中文网

原创

ConcurrentHashMap 比 Hashtable 更快,因其分段锁(JDK7)或 CAS+synchronized 单节点锁(JDK8+),而 Hashtable 全表同步;CopyOnWriteArrayList 适合读多写少、允许最终一致性的场景;BlockingQueue 中 ArrayBlockingQueue 有界稳定,LinkedBlockingQueue 无界易OOM;ThreadLocal 需及时 remove 避免内存泄漏。

java并发编程中的并发容器与线程安全

ConcurrentHashMap 为什么比 Hashtable 更快

因为 ConcurrentHashMap 不锁整个表,而是把桶数组分段加锁(JDK 7)或用 volatile + CAS + synchronized 控制单个 Node(JDK 8+),而 Hashtable 所有方法都用 synchronized 锁住整个实例。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 高并发读多写少场景,优先选 ConcurrentHashMapHashtable 已基本淘汰,除非维护老代码
  • JDK 8+ 中,ConcurrentHashMapcomputeIfAbsent 是线程安全的,但注意其参数函数不能有副作用,否则可能被重复执行
  • 不要用 ConcurrentHashMap.keySet().iterator() 做遍历时修改操作——它不抛 ConcurrentModificationException,但行为不可靠,应改用 forEachentrySet().parallelStream()

CopyOnWriteArrayList 适合什么场景

CopyOnWriteArrayList 在写操作(add/remove/set)时复制整个底层数组,读操作完全无锁。这意味着读性能极高、迭代绝对安全,但写操作代价大、内存占用翻倍、且读到的可能是“旧快照”。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 适用于读远多于写、且允许读取延迟(最终一致性)的场景,比如监听器列表、配置白名单缓存
  • 避免在循环中频繁调用 add:每次 add 都触发一次数组复制,O(n) 时间 + O(n) 内存分配
  • 它的 size()get(int) 是弱一致性——调用瞬间返回当前快照长度/元素,但无法反映其他线程刚提交的写入

BlockingQueue 的选择:ArrayBlockingQueue vs LinkedBlockingQueue

两者都是线程安全的阻塞队列,但底层结构和性能特征差异明显。

Programming Helper
Programming Helper

AI代码自动生成器,在AI的帮助下更快地编程

下载

实操建议:

立即学习Java免费学习笔记(深入)”;

  • ArrayBlockingQueue 是有界、基于数组、单锁(ReentrantLock)控制入队出队,吞吐量稳定,内存占用可控;适合对资源上限敏感的场景(如限流缓冲区)
  • LinkedBlockingQueue 默认无界(容易 OOM),基于链表,入队出队分别用两个独立锁(takeLock / putLock),读写可并行,吞吐更高;若指定容量,才真正具备背压能力
  • 别直接用无参构造的 LinkedBlockingQueue 处理外部不可控数据流——生产者过快会撑爆堆内存

ThreadLocalMap 的内存泄漏风险怎么规避

ThreadLocal 的底层是每个线程持有一个 ThreadLocalMap,其中 key 是弱引用的 ThreadLocal 实例,value 是强引用。如果线程长期运行(如线程池中的线程),而 ThreadLocal 又没被显式 remove(),就会导致 value 无法回收,形成内存泄漏。

实操建议:

立即学习Java免费学习笔记(深入)”;

  • 在线程复用场景(如 Web 容器、线程池)中,必须在业务逻辑结束前调用 threadLocal.remove(),尤其在 finally 块里
  • 不要把大对象(如 StringBuilder、缓存 Map)长期绑定在 ThreadLocal 中,即使及时 remove,也可能在 GC 前已造成压力
  • 可以考虑用 InheritableThreadLocal 的子类重写 childValue,但要注意父子线程间的数据拷贝开销

并发容器不是银弹——ConcurrentHashMap 不能替代手动同步复杂复合操作,CopyOnWriteArrayList 不适合高频写,BlockingQueue 的边界策略直接影响系统稳定性,而 ThreadLocal 的生命周期必须和线程生命周期对齐。这些细节一旦忽略,问题往往在线上压测或流量高峰时才暴露。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

267

2025.12.04

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

267

2025.12.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1031

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

613

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

334

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

235

2025.08.29

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

76

2025.10.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.07.18

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.3万人学习

Java 教程
Java 教程

共578课时 | 81.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号