java 14 引入 concurrenthashmap.newkeyset() 提供线程安全的 concurrenthashset 视图,因标准库从未提供 public concurrenthashset 类,它替代了冗长的 collections.newsetfrommap(new concurrenthashmap()),具备完全线程安全、弱一致性迭代、无锁扩容等特性。

Java 14 引入了 ConcurrentHashMap.newKeySet(),它能直接返回一个线程安全的 Set 视图——本质上是基于 ConcurrentHashMap 实现的 ConcurrentHashSet。它不是独立类,而是一个轻量、高效、无额外依赖的并发集合构建方式。
为什么不用 new ConcurrentHashSet()?
Java 标准库至今(JDK 21)**没有提供 `ConcurrentHashSet` 这个公开类**。过去开发者常通过 `Collections.newSetFromMap(new ConcurrentHashMap())` 模拟,但写法冗长且易出错。`newKeySet()` 是官方推荐的替代方案,语义清晰、开销更低、API 更简洁。
newKeySet() 的核心特性
该方法返回的 Set 具备以下关键行为:
- 完全线程安全:所有操作(add/remove/contains/size)都由底层 ConcurrentHashMap 保证原子性与可见性;
- 弱一致性迭代器:遍历时不会抛 ConcurrentModificationException,但不保证反映最新修改(适合读多写少场景);
- 无锁扩容:继承 ConcurrentHashMap 的分段扩容机制,高并发下性能稳定;
-
默认初始容量为 16,负载因子 0.75,和 ConcurrentHashMap 一致,可传参定制:
newKeySet(initialCapacity)。
实际用法示例
直接创建并使用:
(注意:需 JDK 14+)Set<string> concurrentSet = ConcurrentHashMap.<string>newKeySet();
concurrentSet.add("task-1");
concurrentSet.add("task-2");
// 多线程环境下安全调用
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 0; i concurrentSet.add("item-" + ThreadLocalRandom.current().nextInt(100)));
}
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("Size: " + concurrentSet.size()); // 结果准确</string></string>
和 CopyOnWriteArraySet 的区别
两者都线程安全,但适用场景不同:
- newKeySet():适合中高并发、读写混合、元素数量中等(千级到百万级)的场景,内存占用低,写操作不阻塞读;
- CopyOnWriteArraySet:适用于读极多、写极少(如监听器列表)、集合较小的场景;每次写都复制整个数组,写入成本高,不适合高频更新。










