在Java中如何使用ConcurrentHashMap实现高并发映射

来源:站长源码作者:松本一香头衔:网络博主
导读:本期聚焦于小伙伴创作的《在Java中如何使用ConcurrentHashMap实现高并发映射》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《在Java中如何使用ConcurrentHashMap实现高并发映射》有用,将其分享出去将是对创作者最好的鼓励。

在Java并发编程场景中,当多个线程需要同时操作同一个映射结构时,普通的HashMap会因为线程不安全出现数据错乱、死循环等问题,而Hashtable虽然线程安全但整体加锁的方式会导致性能瓶颈。ConcurrentHashMap通过分段锁、CAS等机制实现了高效的线程安全映射操作,是处理高并发映射场景的首选工具。

ConcurrentHashMap核心特性

ConcurrentHashMap从Java 8开始摒弃了之前的分段锁设计,改用Node数组+链表+红黑树的结构,结合CAS操作和synchronized关键字实现细粒度锁控制,核心特性如下:

  • 线程安全:所有操作都保证在多线程环境下的正确性,不会出现数据不一致问题
  • 高并发性能:读操作完全无锁,写操作仅对当前操作的节点加锁,并发度远高于Hashtable
  • 弱一致性:迭代器遍历的是迭代器创建时的映射快照,不会抛出ConcurrentModificationException
  • 不支持空键空值:和HashMap不同,ConcurrentHashMap的key和value都不能为null,避免多线程下的歧义

常用基础操作方法

创建与初始化

可以通过无参构造或者指定初始容量、负载因子、并发级别的方式创建ConcurrentHashMap实例:

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapDemo {
    public static void main(String[] args) {
        // 无参构造,默认初始容量16,负载因子0.75
        ConcurrentHashMap<String, Integer> map1 = new ConcurrentHashMap<>();
        
        // 指定初始容量为32
        ConcurrentHashMap<String, Integer> map2 = new ConcurrentHashMap<>(32);
        
        // 指定初始容量和负载因子
        ConcurrentHashMap<String, Integer> map3 = new ConcurrentHashMap<>(32, 0.8f);
        
        // 指定初始容量、负载因子、并发级别(Java 8后并发级别仅作为初始容量的参考,不再决定分段数量)
        ConcurrentHashMap<String, Integer> map4 = new ConcurrentHashMap<>(32, 0.8f, 16);
    }
}

增删改查操作

基础的映射操作和HashMap类似,但是所有操作都是线程安全的:

import java.util.concurrent.ConcurrentHashMap;

public class BasicOperationDemo {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        
        // 添加/更新键值对,如果key不存在则插入,存在则覆盖
        map.put("apple", 10);
        map.put("banana", 20);
        
        // 获取值,key不存在返回null
        Integer appleCount = map.get("apple"); // 返回10
        Integer orangeCount = map.get("orange"); // 返回null
        
        // 移除键值对,key存在则移除
        map.remove("banana");
        
        // 判断key是否存在
        boolean hasApple = map.containsKey("apple"); // 返回true
        
        // 获取所有key的集合
        System.out.println(map.keySet()); // 输出[apple]
        
        // 获取所有值的集合
        System.out.println(map.values()); // 输出[10]
    }
}

高并发场景下的特殊操作方法

ConcurrentHashMap提供了很多原子性的复合操作方法,避免多线程下先检查后操作的竞态问题:

原子性插入与更新

使用putIfAbsentcomputemerge等方法可以实现原子性的复合操作:

import java.util.concurrent.ConcurrentHashMap;

public class AtomicOperationDemo {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        
        // putIfAbsent:如果key不存在则插入,存在则返回已有值,原子操作
        Integer result1 = map.putIfAbsent("apple", 10); // 返回null,插入成功
        Integer result2 = map.putIfAbsent("apple", 20); // 返回10,插入失败
        
        // compute:根据key和旧值计算新值,旧值为null时表示key不存在
        map.compute("apple", (key, oldValue) -> oldValue + 5); // apple的值变为15
        map.compute("banana", (key, oldValue) -> oldValue == null ? 1 : oldValue + 1); // 插入banana=1
        
        // merge:如果key不存在则插入value,存在则将旧值和value用函数合并
        map.merge("apple", 3, Integer::sum); // apple的值变为15+3=18
        map.merge("orange", 5, Integer::sum); // 插入orange=5
    }
}

批量操作方法

ConcurrentHashMap提供了遍历、搜索、归约等批量操作,这些操作都是弱一致性的,不会阻塞其他线程的操作:

import java.util.concurrent.ConcurrentHashMap;
import java.util.List;

public class BatchOperationDemo {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
        map.put("a", 1);
        map.put("b", 2);
        map.put("c", 3);
        
        // forEach:遍历所有键值对
        map.forEach((key, value) -> System.out.println(key + ":" + value));
        
        // search:搜索第一个满足条件的键值对,返回结果
        String result = map.search(1, (key, value) -> value > 2 ? key : null); // 返回"c"
        
        // reduce:归约操作,计算所有值的和
        Integer sum = map.reduceValues(1, Integer::sum); // 返回6
        
        // 转换为List
        List<String> keyList = map.keys().asList();
    }
}

使用注意事项

  • 不要使用null作为key或value,否则会抛出NullPointerException
  • 迭代器的弱一致性特性意味着遍历过程中其他线程的修改可能不会反映到当前遍历结果中,如果需要强一致性遍历,需要额外加锁控制
  • 虽然ConcurrentHashMap是线程安全的,但是多个操作的组合如果不是原子操作,仍然可能出现竞态问题,比如先判断存在再删除的操作,需要使用remove(key, value)原子方法替代
  • Java 8之前的ConcurrentHashMap并发级别参数在Java 8及之后仅作为初始容量的参考,不再决定实际的分段数量,不需要特意设置过大的并发级别

和其他线程安全映射的对比

映射类型线程安全实现方式读操作性能写操作性能适用场景
Hashtable全表synchronized锁几乎不再使用,仅兼容旧代码
Collections.synchronizedMap全表synchronized锁并发量极低的场景
ConcurrentHashMapCAS+细粒度synchronized锁高(无锁)高(仅锁当前节点)高并发读写映射场景

ConcurrentHashMapJava高并发映射操作修改时间:2026-07-04 13:07:01

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。