本文正在参加「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来实现功能,而这个方法在删除大量元素时效率极低,因此不建议使用第一种方法。