精通 Java ConcurrentHashMap:操作、示例与最佳实践
Java ConcurrentHashMap
探索 Java ConcurrentHashMap 类,学习创建与操作技巧,通过实战代码示例发现其核心优势。
ConcurrentHashMap 类来自 Java 集合框架,提供线程安全的 Map 实现。多线程可并发读写而不破坏 Map 完整性。
它实现 ConcurrentMap 接口,属于 java.util.concurrent 包。
创建 ConcurrentHashMap
先导入类:
import java.util.concurrent.ConcurrentHashMap;
再实例化。可指定初始容量和负载因子,或使用默认值。
// 容量 8、负载因子 0.6
ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);
参数
capacity— 初始桶数量(示例为 8)。loadFactor— 达到 60% 满时触发扩容。
默认构造器创建容量 16、负载因子 0.75 的 Map:
ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();
从现有 Map 创建 ConcurrentHashMap
可用任意其他 Map 的条目填充新 ConcurrentHashMap。
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
class Main {
public static void main(String[] args) {
HashMap<String, Integer> evenNumbers = new HashMap<>();
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
System.out.println("HashMap: " + evenNumbers);
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(evenNumbers);
numbers.put("Three", 3);
System.out.println("ConcurrentHashMap: " + numbers);
}
}
输出
HashMap: {Four=4, Two=2}
ConcurrentHashMap: {Four=4, Two=2, Three=3}
ConcurrentHashMap 的关键方法
插入元素
put(K key, V value)— 添加或替换映射。putAll(Map<? extends K, ? extends V> m)— 批量插入。putIfAbsent(K key, V value)— 键不存在时才插入。
ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>();
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
evenNumbers.putIfAbsent("Six", 6);
System.out.println("Even numbers: " + evenNumbers);
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.putAll(evenNumbers);
System.out.println("Numbers: " + numbers);
输出
Even numbers: {Six=6, Four=4, Two=2}
Numbers: {Six=6, One=1, Four=4, Two=2}
访问元素
使用视图集合或键值获取方法。
entrySet()、keySet()、values()— 返回条目、键、值集合。get(K key)— 获取值,缺失返回null。getOrDefault(K key, V defaultValue)— 获取值或提供的默认值。
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
System.out.println("Map: " + numbers);
System.out.println("Entries: " + numbers.entrySet());
System.out.println("Keys: " + numbers.keySet());
System.out.println("Values: " + numbers.values());
int val = numbers.get("Three");
System.out.println("get(\"Three\"): " + val);
int def = numbers.getOrDefault("Five", 5);
System.out.println("getOrDefault(\"Five\", 5): " + def);
输出
Map: {One=1, Two=2, Three=3}
Entries: [One=1, Two=2, Three=3]
Keys: [One, Two, Three]
Values: [1, 2, 3]
get("Three"): 3
getOrDefault("Five", 5): 5
移除条目
remove(K key)— 删除映射并返回其值。remove(K key, V value)— 仅当当前值匹配时删除;返回布尔值。
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
int removed = numbers.remove("Two");
System.out.println("移除的值: " + removed);
boolean deleted = numbers.remove("Three", 3);
System.out.println("条目 {Three=3} 是否移除? " + deleted);
System.out.println("更新后的 Map: " + numbers);
输出
移除的值: 2
条目 {Three=3} 移除? true
更新后的 Map: {One=1}
批量操作
这些方法利用并行性高效处理大型 Map。
forEach()
遍历条目,可选并行,应用消费者。
numbers.forEach(4, (k, v) -> System.out.println("key: " + k + " value: " + v));
// 带转换器:
numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + ", "));
此处 4 为并行阈值 — Map 至少 4 个元素时操作可能并发执行。
search()
查找满足谓词的条目。返回首个匹配。
String key = numbers.search(4, (k, v) -> v == 3 ? k : null);
System.out.println("搜索到的键: " + key);
reduce()
使用归约器聚合值。适用于求和、求积或自定义累加。
int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2);
System.out.println("值的总和: " + sum);
ConcurrentHashMap 与 HashMap 对比
- 线程安全 —
ConcurrentHashMap允许安全并发修改;HashMap非线程安全。 - 批量方法 —
ConcurrentHashMap提供forEach、search、reduce供并行处理。
为何使用 ConcurrentHashMap?
- 支持高并发且阻塞极少。
- 内部分为 16 个段,最多 16 线程可同时修改不同段。
putIfAbsent等操作防止意外覆盖。- 内置同步免去外部锁。
java
- MATLAB 数值类型详解:存储、转换与范围查询
- 精通 Java 运算符:类型、语法与实战示例
- Java 注释:类型、用法与最佳实践
- 精通 Java 增强 for 循环:语法、示例与最佳实践
- 精通 Java 字符串:创建、方法与最佳实践
- 精通 Java 接口:概念、实现与最佳实践
- 精通 Java 匿名内部类:定义、语法与实战示例
- 精通 Java Try-With-Resources:自动资源管理详解
- Java 注解详解:类型、放置位置与实战示例
- Java 断言实战指南:尽早发现 Bug 与保障代码可靠性
- 掌握 Java 集合算法:排序、打乱、搜索与更多实用操作
- Java 生成随机数实战:Random 与 Math.random 详解