本文翻译自:Why there is no ConcurrentHashSet against ConcurrentHashMap

HashSet is based on HashMap. HashSet基于HashMap。

If we look at HashSet<E> implementation, everything is been managed under HashMap<E,Object> . 如果我们查看HashSet<E>实现,则所有内容都在HashMap<E,Object>下进行管理。

<E> is used as a key of HashMap . <E>用作HashMap的键。

And we know that HashMap is not thread safe. 我们知道HashMap不是线程安全的。 That is why we have ConcurrentHashMap in Java. 这就是我们在Java中使用ConcurrentHashMap原因。

Based on this, I am confused that why we don't have a ConcurrentHashSet which should be based on the ConcurrentHashMap ? 基于此,我很困惑为什么我们没有ConcurrentHashSet应该基于ConcurrentHashMap

Is there anything else that I am missing? 还有什么我想念的吗? I need to use Set in a multi-threaded environment. 我需要在多线程环境中使用Set

Also, If I want to create my own ConcurrentHashSet can I achieve it by just replacing the HashMap to ConcurrentHashMap and leaving the rest as is? 另外,如果我想创建自己的ConcurrentHashSet ,我可以通过将HashMap替换为ConcurrentHashMap并将其余部分原样保留来实现它吗?


#1楼

参考:https://stackoom.com/question/TL60/为什么ConcurrentHashMap没有ConcurrentHashSet


#2楼

It looks like Java provides a concurrent Set implementation with its ConcurrentSkipListSet . 看起来Java提供了ConcurrentSkipListSet的并发Set实现。 A SkipList Set is just a special kind of set implementation. SkipList Set只是一种特殊的集合实现。 It still implements the Serializable, Cloneable, Iterable, Collection, NavigableSet, Set, SortedSet interfaces. 它仍然实现Serializable,Cloneable,Iterable,Collection,NavigableSet,Set,SortedSet接口。 This might work for you if you only need the Set interface. 如果您只需要Set接口,这可能对您有用。


#3楼

Set<String> mySet = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());

#4楼

import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<E>{private final ConcurrentMap<E, Object> theMap;private static final Object dummy = new Object();public ConcurrentHashSet(){theMap = new ConcurrentHashMap<E, Object>();}@Overridepublic int size() {return theMap.size();}@Overridepublic Iterator<E> iterator(){return theMap.keySet().iterator();}@Overridepublic boolean isEmpty(){return theMap.isEmpty();}@Overridepublic boolean add(final E o){return theMap.put(o, ConcurrentHashSet.dummy) == null;}@Overridepublic boolean contains(final Object o){return theMap.containsKey(o);}@Overridepublic void clear(){theMap.clear();}@Overridepublic boolean remove(final Object o){return theMap.remove(o) == ConcurrentHashSet.dummy;}public boolean addIfAbsent(final E o){Object obj = theMap.putIfAbsent(o, ConcurrentHashSet.dummy);return obj == null;}
}

#5楼

As pointed by this the best way to obtain a concurrency-able HashSet is by means of Collections.synchronizedSet() 正如指出由此 ,获得并发能够HashSet的最好的办法是借助于Collections.synchronizedSet()

Set s = Collections.synchronizedSet(new HashSet(...));

This worked for me and I haven't seen anybody really pointing to it. 这对我有用,我没有看到任何人真正指向它。

EDIT This is less efficient than the currently aproved solution, as Eugene points out, since it just wraps your set into a synchronized decorator, while a ConcurrentHashMap actually implements low-level concurrency and it can back your Set just as fine. 编辑这比当前被批准的解决方案效率低,正如Eugene所指出的那样,因为它只是将你的集合包装成一个同步的装饰器,而ConcurrentHashMap实际上实现了低级别的并发性,它可以支持你的Set一样好。 So thanks to Mr. Stepanenkov for making that clear. 所以感谢Stepanenkov先生说清楚了。

http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set- http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet-java.util.Set-


#6楼

使用Guava 15,您还可以使用:

Set s = Sets.newConcurrentHashSet();

为什么ConcurrentHashMap没有ConcurrentHashSet相关推荐

  1. 利用ConcurrentHashMap来实现一个ConcurrentHashSet

    利用ConcurrentHashMap来实现一个ConcurrentHashSet package hashset;import java.io.Serializable; import java.u ...

  2. java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?

    java 线程中创建线程 在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet. java.util.concurrent包甚至没有一个名为Concurren ...

  3. 如何在Java 8中创建线程安全的ConcurrentHashSet?

    在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet. java.util.concurrent包甚至没有一个名为ConcurrentHashSet的类,但是 ...

  4. SpringBean默认是单例的,高并发情况下,如何保证并发安全?

    以下文章来源方志朋的博客,回复"666"获面试宝典 Spring的bean默认都是单例的,某些情况下,单例是并发不安全的,以Controller举例,问题根源在于,我们可能会在Co ...

  5. 双重检查锁,原来是这样演变来的,你了解吗

    最近在看Nacos的源代码时,发现多处都使用了"双重检查锁"的机制,算是非常好的实践案例.这篇文章就着案例来分析一下双重检查锁的使用以及优势所在,目的就是让你的代码格调更加高一个层 ...

  6. Spring中的Bean默认是单例还是多例?如何保证并发安全?

    点击关注公众号,实用技术文章及时了解 Spring的bean默认都是单例的,某些情况下,单例是并发不安全的,以Controller举例,问题根源在于,我们可能会在Controller中定义成员变量,如 ...

  7. Spring 框架(Spring Framework)使用详解

    概述 Spring 体系概述 Spring 是于2003年兴起的一个 full-stack 轻量级的 Java 开源框架,由 Rod Johnson 创建,使用 Spring 可以更快.更轻松.更安全 ...

  8. java中级开发面试总结

    中级开发面试总结 分布式事务的四种解决方案 一.两阶段提交(2PC) 两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些 ...

  9. 【JDK8语法新特性】:超全总结{lamda,stream,optional,新日期类API},JDK8对策略模式支持,可以直接贴代码运行测试。

    文章目录 Java8新特性 速度快 代码更少(增加了新的语法,lamda表达式)(主要) 强大的Stream API(主要) 便于并行 最大减少空指针异常(Optional API) 提供了线程安全的 ...

最新文章

  1. linux I/O--I/O多路复用--select总结(三)
  2. 4款bt search
  3. 与中石油分享SOA成功实践
  4. Realsense安装使用过程问题汇总
  5. android内核调试的步骤
  6. 【资料分享】500篇干货解读人工智能新时代
  7. 麦本本从u盘启动计算机,麦本本怎么设计u盘启动顺序
  8. echarts官网折线图
  9. WES7和WES2009的功能比较
  10. Vue加载组件、动态加载组件的几种方式
  11. 生物信息分析中的reads是什么
  12. 微信赌场——H5棋牌游戏渗透之旅
  13. 华为EMUI10基本可以升鸿蒙,华为EMUI11发布,12月可升级为鸿蒙OS国产操作系统
  14. 正则表达式,密码规则
  15. mini2440 linux驱动程序,mini2440的led的Linux驱动程序
  16. 20不努力,30做助理(转载)
  17. sanic 应用(2)
  18. CarSim-车辆模型
  19. 凸包+凹包+凸边凹化算法
  20. php表达式ax 2 bx c=0,设a,b,c为互不相等的非零实数,求证:方程ax2+2bx+c=0,bx2+2cx+a=0,cx2+...

热门文章

  1. 如何判定选择的日期与当前日期的前后关系
  2. linux内核被加载的过程
  3. 常用 API 函数(7): 位图、图标和光栅运算函数
  4. 网站运营直通车——7天精通SEO
  5. IOCP 写服务程序时的关键问题研究[转]
  6. HDU 4404 Worms(多边形和圆相交)
  7. 开启html元素的编辑模式contenteditable=true
  8. [其他]Ubuntu安装genymotion后unable to load VirtualBox engine
  9. linux下 mysql5.5数据库迁移操作
  10. (一) 开天辟地入门篇(mvc)