0

0

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

P粉602998670

P粉602998670

发布时间:2026-01-07 15:39:08

|

675人浏览过

|

来源于php中文网

原创

concurrenthashmap 比 hashtable 更常用,因其采用分段锁(jdk 7)或 cas + synchronized(jdk 8+)实现桶级锁定,避免全表锁瓶颈;但 size() 非原子、不支持 null、computexxx 方法需防死锁与阻塞。

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

ConcurrentHashMap 为什么比 Hashtable 更常用

因为 ConcurrentHashMap 在保证线程安全的同时,避免了 Hashtable 全表锁的性能瓶颈。它采用分段锁(JDK 7)或 CAS + synchronized(JDK 8+)策略,只锁定桶(bin)级节点,允许多个线程并发读写不同段。

常见误用:把 ConcurrentHashMap 当作“完全无锁”容器——实际在扩容、computeIfAbsent 或迭代过程中仍可能阻塞部分线程。

  • putget 基本是无锁的(JDK 8+),但 size() 不是原子操作,返回的是估算值;如需精确计数,改用 mappingCount()
  • 不支持 null 作为 key 或 value,否则抛 NullPointerException;而 HashMap 允许一个 null key
  • 迭代器弱一致性:遍历时允许其他线程修改,不会抛 ConcurrentModificationException,但可能漏掉刚插入的元素,也不会反映删除后的状态

什么时候该用 Collections.synchronizedMap

仅当已有 HashMap 实例且改造成本低、并发度不高(如配置缓存、单写多读场景)、又不想引入新依赖时才考虑。它本质是对所有 public 方法加同一把 mutex 锁,等价于手动同步整个 map 实例。

典型陷阱:以为包装后就“线程安全”,却在外部做复合操作(如先 containsKeyput)——这仍是竞态条件。

玻璃钢企业网站源码1.5
玻璃钢企业网站源码1.5

本程序源码为asp与acc编写,并没有花哨的界面与繁琐的功能,维护简单方便,只要你有一些点点asp的基础,二次开发易如反掌。 1.功能包括产品,新闻,留言簿,招聘,下载,...是大部分中小型的企业建站的首选。本程序是免费开源,只为大家学习之用。如果用于商业,版权问题概不负责。1.采用asp+access更加适合中小企业的网站模式。 2.网站页面div+css兼容目前所有主流浏览器,ie6+,Ch

下载

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

  • 必须显式同步整个操作块:
     synchronized (syncMap) {
        if (!syncMap.containsKey(key)) {
            syncMap.put(key, value);
        }
    }
  • 迭代必须手动同步:
     synchronized (syncMap) {
        for (Map.Entry<K,V> e : syncMap.entrySet()) {
            // ...
        }
    }
  • 相比 ConcurrentHashMap,吞吐量在高并发下明显下降,尤其写多场景

CopyOnWriteArrayList 适合 Map 吗?

不适合。Java 没有 CopyOnWriteMap 标准实现,也不推荐自己封装。因为 CopyOnWrite 的核心代价是每次写都复制整个底层数组,对键值对集合来说内存和 CPU 开销过大,且无法保证 key-value 关联的原子性。

如果真需要类似语义(读极多、写极少、容忍短暂不一致),可考虑:

  • volatile 引用指向不可变 Map(如 Map.copyOf(map)ImmutableMap
  • 读取时直接访问 volatile 引用;写入时重建新 map 并原子更新引用
  • 注意:这种模式下,写操作不是线程安全的,需额外同步写入口

ConcurrentHashMap 的 computeXXX 方法怎么避坑

computeIfAbsentcomputeIfPresent 等方法看似方便,但容易因函数副作用或阻塞导致死锁或性能恶化——它们在持有内部锁期间执行传入的 remappingFunction

  • 禁止在 lambda 中调用本 map 的其他修改方法(如再调 put),可能引发死锁
  • 避免耗时操作(如 IO、远程调用),否则会拖慢整个桶的写入,影响并发度
  • 若计算逻辑可能抛异常,需确保异常处理得当;未捕获异常会导致本次操作失败,且锁会被释放,但 map 状态不变
  • 示例安全用法:
    map.computeIfAbsent(key, k -> {
        // 快速构造新值,不访问 map 自身
        return new ExpensiveObject(k);
    });
真正难处理的从来不是“选哪个容器”,而是复合操作的原子性边界——比如“检查存在性 + 更新值 + 记录日志”这一串动作,无论用哪种 map,都得靠外层同步或事务机制兜底。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

254

2023.09.22

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

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

1089

2024.03.01

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

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

75

2025.10.23

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

215

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

192

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

61

2026.01.05

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

77

2025.09.05

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

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

精品课程

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

共23课时 | 4.3万人学习

C# 教程
C# 教程

共94课时 | 11.2万人学习

Java 教程
Java 教程

共578课时 | 80.9万人学习

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

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