温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Set集合线程安全吗

发布时间:2026-07-24 12:17:18 来源:亿速云 阅读:105 作者:小樊 栏目:编程语言

Set 集合本身不是线程安全的,是否线程安全取决于具体实现类

下面按常见 Set 实现来说明:


一、常见 Set 是否线程安全

Set 实现 是否线程安全 说明
HashSet ❌ 不安全 非线程安全,多线程并发修改可能抛异常或数据错乱
TreeSet ❌ 不安全 同上
LinkedHashSet ❌ 不安全 同上
Collections.synchronizedSet(...) ✅ 安全 包装后的线程安全 Set
CopyOnWriteArraySet ✅ 安全 基于写时复制,适合读多写少
ConcurrentHashMap.newKeySet() ✅ 安全 JDK 8+,基于 ConcurrentHashMap

二、为什么 HashSet 不是线程安全?

HashSet 底层是 HashMap,在并发场景下可能出现:

  • 数据丢失
  • 死循环(JDK 7 及以前扩容时)
  • ConcurrentModificationException

示例(不安全):

Set<Integer> set = new HashSet<>();
new Thread(() -> {
    for (int i = 0; i < 1000; i++) {
        set.add(i);
    }
}).start();

三、如何保证 Set 的线程安全?

✅ 方式 1:使用 synchronizedSet

Set<Integer> set = Collections.synchronizedSet(new HashSet<>());
  • 所有操作加锁
  • 适合并发量不大的场景

⚠️ 遍历时仍需手动同步:

synchronized (set) {
    for (Integer i : set) {
        ...
    }
}

✅ 方式 2:使用 CopyOnWriteArraySet

Set<Integer> set = new CopyOnWriteArraySet<>();
  • 读操作无锁,性能高
  • 写操作复制整个数组,代价大
  • 适合:读多写少、集合较小

✅ 方式 3:使用 ConcurrentHashMap.newKeySet()(推荐)

Set<Integer> set = ConcurrentHashMap.newKeySet();
  • 高并发性能好
  • 不需要额外同步
  • 实际开发中最常用

四、如何选择?

场景 推荐
高并发、频繁读写 ConcurrentHashMap.newKeySet()
读多写少 CopyOnWriteArraySet
简单同步 Collections.synchronizedSet
单线程 HashSet

✅ 总结一句话

Set 接口本身不保证线程安全,只有特定实现(如 ConcurrentHashMap.newKeySet())才是线程安全的。

如果你有具体使用场景(如缓存、去重、并发计数),我可以帮你选最合适的 Set。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI