2.1 为什么没有针对ConcurrentHashMap的ConcurrentHashSet?| Java Debug 笔记

1,281 阅读1分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>

提问:为什么没有针对ConcurrentHashMap的ConcurrentHashSet?

众所周知,HashSet基于HashMap。

如果我们看一下HashSet实现,则会发现所有内容都在被HashMap<E,Object>管理。

同时,我们知道这HashMap不是线程安全的。这就是我们使用Java的ConcurrentHashMap的原因。(当然,hashtable也行)

基于以上两个条件,我感到困惑的是,为什么我们没有基于 ConcurrentHashMap的ConcurrentHashSet?

我错过了什么至关重要的知识点了吗?我需要Set在多线程环境中使用。

另外,如果我想自己创建一个支持多线程的HashSet,是否ConcurrentHashSet可以通过仅替换HashMap为ConcurrentHashMap,并且其余代码和HashSet保持一致来实现?

回答1: Java中并没有内置的ConcurrentHashMap,因为你总可以通过使用一个map生成一个set。而map具有很多种,因此你也可以根据map生成很多中set(包括ConcurrentHashSet)。

在Java 8以前,你可以通过以下方式生成一个支持并发的HashSet

Collections.newSetFromMap(map)

在Java 8以后, 你可以通过一个ConcurrentHashMap直接获取到一个“ConcurrentHashSet”,

HashSet set = ConcurrentHashMap.newKeySet();

这种方式相对于上一种更加的简单,因为上一种方法需要我们生成一个map,甚至很可能这个map是空的,只是为了创建一个支持多线程的HashSet而存在,这无疑是对资源的浪费。

需要注意的是:

Collections.newSetFromMap创建一个SetFromMap。SetFromMap.removeAll方法委托KeySetView.removeAll来实现功能,而这个方法在删除大量元素时效率极低,因此不建议使用第一种方法。