Set 集合本身不是线程安全的,是否线程安全取决于具体实现类。
下面按常见 Set 实现来说明:
| Set 实现 | 是否线程安全 | 说明 |
|---|---|---|
HashSet |
❌ 不安全 | 非线程安全,多线程并发修改可能抛异常或数据错乱 |
TreeSet |
❌ 不安全 | 同上 |
LinkedHashSet |
❌ 不安全 | 同上 |
Collections.synchronizedSet(...) |
✅ 安全 | 包装后的线程安全 Set |
CopyOnWriteArraySet |
✅ 安全 | 基于写时复制,适合读多写少 |
ConcurrentHashMap.newKeySet() |
✅ 安全 | JDK 8+,基于 ConcurrentHashMap |
HashSet 底层是 HashMap,在并发场景下可能出现:
ConcurrentModificationException示例(不安全):
Set<Integer> set = new HashSet<>();
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
set.add(i);
}
}).start();
synchronizedSetSet<Integer> set = Collections.synchronizedSet(new HashSet<>());
⚠️ 遍历时仍需手动同步:
synchronized (set) {
for (Integer i : set) {
...
}
}
CopyOnWriteArraySetSet<Integer> set = new CopyOnWriteArraySet<>();
ConcurrentHashMap.newKeySet()(推荐)Set<Integer> set = ConcurrentHashMap.newKeySet();
| 场景 | 推荐 |
|---|---|
| 高并发、频繁读写 | ConcurrentHashMap.newKeySet() |
| 读多写少 | CopyOnWriteArraySet |
| 简单同步 | Collections.synchronizedSet |
| 单线程 | HashSet |
Set 接口本身不保证线程安全,只有特定实现(如
ConcurrentHashMap.newKeySet())才是线程安全的。
如果你有具体使用场景(如缓存、去重、并发计数),我可以帮你选最合适的 Set。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。