讲师中心 微信公众号

工具推荐

视频效率加速
Seko
Seko

AI短剧一键生成成片

剧云
剧云

中文短剧剧本制作平台

Laper
Laper

剧本策划到成片协作

AniShort
AniShort

AI短剧协同制作平台

Java集合框架中的集合类与多线程操作

云辰君_6027

云辰君_6027

发布时间:2026-01-07 00:21:24

|

810人浏览过

|

来源于php中文网

原创

不会立即抛 ConcurrentModificationException,而是在迭代时检测到 modCount 不一致才抛出;多线程直接 add() 可能导致数组越界、元素覆盖或结果丢失。

java集合框架中的集合类与多线程操作

ArrayList 在多线程下直接 add() 会抛 ConcurrentModificationException 吗?

不会立即抛 ConcurrentModificationException,但大概率在迭代时崩溃。这个异常不是在写操作(如 add())时触发,而是在后续调用 iterator().next() 或 forEach() 等遍历方法检测到结构被并发修改时才抛出。

  • ArrayList 的 modCount 字段记录结构性修改次数,Iterator 持有初始 expectedModCount,不一致即触发异常
  • 多个线程同时 add() 可能导致数组越界、元素覆盖或 NullPointerException,因为 add() 不是原子操作:先检查容量 → 扩容(可能复制数组)→ 写入元素
  • 即使没抛异常,结果也是不可预测的——比如两个线程同时 add("a"),最终可能只插入一个,或数组处于中间状态

哪些 Java 集合类天生支持多线程安全?

真正线程安全的集合类极少,且各有适用边界。注意“线程安全”仅指单个操作原子,不等于复合操作自动安全。

  • Vector 和 Stack:所有 public 方法加了 synchronized,但性能差、已基本被弃用
  • Hashtable:类似 Vector,get() 和 put() 都同步,但不支持 null 键/值,且迭代仍需手动同步
  • ConcurrentHashMap:推荐首选,分段锁(JDK 7)或 cas + synchronized(JDK 8+),支持高并发读写,get() 无锁,put() 锁粒度为桶(bin)
  • CopyOnWriteArrayList:写操作复制整个数组,读操作完全无锁;适合读远多于写的场景(如监听器列表),但内存开销大、写延迟高

ConcurrentHashMap 的 computeIfAbsent() 为什么比 putIfAbsent() 更适合初始化缓存?

因为 computeIfAbsent() 能保证:键不存在时,只会执行一次传入的 mapping function;而 putIfAbsent() 无法避免重复构造值对象。

JavaScript 测试模式
JavaScript 测试模式

使用 Jest、Vitest 和 Testing Library 实施全面的测试策略,包括单元测试、集成测试和端到端测试,涵盖模拟、测试夹具和测试驱动开发。在编

下载
Map<String, List<String>> cache = new ConcurrentHashMap<>();
// ❌ 可能多次 new ArrayList(),即使 key 已存在
cache.putIfAbsent("key", new ArrayList<>());

// ✅ 只有 key 真正不存在时,lambda 才执行一次
cache.computeIfAbsent("key", k -> new ArrayList<>());
  • computeIfAbsent() 内部对目标桶加锁,确保 mapping function 不会被并发调用多次
  • 若 mapping function 耗时(如查数据库、解析 JSON),重复执行会造成资源浪费甚至业务错误
  • 注意:mapping function 内不能调用该 map 的其他写方法(如 put()),否则可能死锁

用 Collections.synchronizedList() 包装 ArrayList 还需要额外同步吗?

需要。包装后单个方法(如 add()、get())是线程安全的,但复合操作(如“检查是否存在再添加”)仍是竞态点。

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

List<String> list = Collections.synchronizedList(new ArrayList<>());
// ❌ 以下三行不是原子操作:可能两个线程同时通过 if 判断,都执行 add()
if (!list.contains("x")) {
    list.add("x"); // ← 中间可能被其他线程插入 "x"
}
  • 必须用 synchronized(list) 显式包裹整个逻辑块
  • 迭代时也必须手动同步,否则仍可能抛 ConcurrentModificationException:synchronized(list) { for (String s : list) { ... } }
  • 这种包装只是“语法糖”,底层仍是粗粒度锁,吞吐量不如 ConcurrentHashMap 或 CopyOnWriteArrayList
实际并发集合选型,关键不在“是否线程安全”,而在“你的访问模式是什么”:是高频读+偶发写?还是读写均衡?是否需要弱一致性保证?这些细节一旦忽略,表面安全的代码照样在线上崩得悄无声息。

热门AI工具

更多
UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

函子Zion

一款支持AI搭建、可视化编辑和多端发布的全栈无代码开发平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2355

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3862

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1276

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

4499

2025.09.10

string转int
string转int

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

7559

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

569

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

php中foreach用法
php中foreach用法

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

838

2025.12.04

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

40

2026.11.12

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn