咨询区

  • Sebastian

在 .NET 框架中并没有线程安全的 ConcurrentHashSet 类,我想模仿 ConcurrentDictionary 来实现一个,目前写了一下桩代码。

public class ConcurrentHashSet<TElement> : ISet<TElement>
{private readonly ConcurrentDictionary<TElement, object> _internal;public ConcurrentHashSet(IEnumerable<TElement> elements = null){_internal = new ConcurrentDictionary<TElement, object>();if (elements != null)UnionWith(elements);}public void UnionWith(IEnumerable<TElement> other){if (other == null) throw new ArgumentNullException("other");foreach (var otherElement in other)Add(otherElement);}public bool Add(TElement item){return _internal.TryAdd(item, null);}// I am not sure here if that fullfills contract correctlyvoid ICollection<TElement>.Add(TElement item){Add(item);}public bool Contains(TElement item){return _internal.ContainsKey(item);}public bool Remove(TElement item){object ignore;return _internal.TryRemove(item, out ignore);}public int Count{get { return _internal.Count; }}public IEnumerator<TElement> GetEnumerator(){return _internal.Keys.GetEnumerator();}
}

我不确定这代码能否在 foreach 中还能保证原子性,请问是否有更好的实现?

回答区

  • Ben Mosher

我最近遇到了类似的场景,不过我更关注的更高性能的 Add,Contains,Remove 方法,下面是我的实现。

using System.Collections.Generic;
using System.Threading;namespace BlahBlah.Utilities
{public class ConcurrentHashSet<T> : IDisposable{private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);private readonly HashSet<T> _hashSet = new HashSet<T>();#region Implementation of ICollection<T> ...ishpublic bool Add(T item){try{_lock.EnterWriteLock();return _hashSet.Add(item);}finally{if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();}}public void Clear(){try{_lock.EnterWriteLock();_hashSet.Clear();}finally{if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();}}public bool Contains(T item){try{_lock.EnterReadLock();return _hashSet.Contains(item);}finally{if (_lock.IsReadLockHeld) _lock.ExitReadLock();}}public bool Remove(T item){try{_lock.EnterWriteLock();return _hashSet.Remove(item);}finally{if (_lock.IsWriteLockHeld) _lock.ExitWriteLock();}}public int Count{get{try{_lock.EnterReadLock();return _hashSet.Count;}finally{if (_lock.IsReadLockHeld) _lock.ExitReadLock();}}}#endregion#region Disposepublic void Dispose(){if (_lock != null) _lock.Dispose();}#endregion}
}

点评区

实现一个 ConcurrentSet<T> 其实蛮有必要的,你在 github 或者其他第三方网站上会找到很多类似的 ConcurrentSet<T> 的实现,比如:https://pastebin.com/8REHRFFL

如何实现一个线程安全的 ConcurrentHashSet ?相关推荐

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

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

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

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

  3. java 手编线程池_死磕 java线程系列之自己动手写一个线程池

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. (手机横屏看源码更方便) 问题 (1)自己动手写一个线程池需要考虑哪些因素? (2)自己动手写 ...

  4. Java一个线程能否结束另一个永不停止的线程

    在Java中停止一个线程有三种办法 : 1.正常结束执行: 2.发生异常; 3.被其他线程stop(Java官方不建议) 参考:https://docs.oracle.com/javase/8/doc ...

  5. FFmpeg中一个线程获取视频流一个线程执行scale测试代码

    在https://blog.csdn.net/fengbingchun/article/details/94712986 中介绍过如果usb视频流编码类型为rawvideo则无需进行解码,可直接通过a ...

  6. 随笔之如何实现一个线程池

    为什么80%的码农都做不了架构师?>>>    一 缘由:     最近因工作问题,需要实现一个简单的线程池,满足一下要求, 可伸缩,即一旦发现线程不够用,则可以动态增加线程.(至于 ...

  7. 一个线程罢工的诡异事件

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 背景 事情(事故)是这样的,突然收到报警,线上某个应用里业务逻辑没 ...

  8. controller如何保证当前只有一个线程执行_今天我们来聊一聊 Spring 中的线程安全性...

    优质文章,及时送达 Spring与线程安全 Spring作为一个IOC/DI容器,帮助我们管理了许许多多的"bean".但其实,Spring并没有保证这些对象的线程安全,需要由开发 ...

  9. 对tomcat来说,每一个进来的请求(request)都需要一个线程,直到该请求结束。

    这段时间折腾了哈java web应用的压力测试,部署容器是tomcat 7.期间学到了蛮多散碎的知识点,及时梳理总结,构建良好且易理解的知识架构把它们组织起来,以备忘. 对web应用开发者来说,我们很 ...

最新文章

  1. 使用Python,OpenCV缩放照片(忽略宽高比,保持宽高比)
  2. Uploadify导致Chrome频繁崩溃Crash
  3. 【react】使用代理解决跨域问题
  4. java数据结构编程_Java数据结构编程
  5. python自动化办公:文件篇(自动整理文件,一键完成)
  6. 模块之hashlib模块
  7. hashmap删除指定key_HashTable和HashMap的区别详解
  8. PythonOCC 3D图形库学习—创建立方体模型
  9. 应届毕业生面试软件测试工程师时应注意什么?
  10. 宏转录组方法_高级转录组分析和R语言数据可视化第12期 (线上线下同时开课)
  11. 全国二级c语言公共基础知识,全国计算机二级C语言及公共基础知识复习资料
  12. 王佩丰VBA学习笔记
  13. Clover-系统集成功能可能被安全软件阻止,请关闭安全软件后重启Clover的解决方案
  14. 音阶频率对照表_音符频率对应表
  15. vue中配置filemanager-webpack-plugin的报错和解决
  16. ABP理论学习之数据过滤器
  17. 阿里云服务器白嫖和购买教程——学生向
  18. Unity3D脚本中的Awake()和Start()的本质区别
  19. 学习笔记| AS入门(三) 布局篇
  20. 安卓模拟器对应键盘快捷键

热门文章

  1. 【足迹C++primer】52、,转换和继承虚函数
  2. 思科加强生成树性能的属性(Portfast /Uplinkfast/BackboneFast)与RSTP的关系
  3. 第四章例题、心得及问题。
  4. 硬盘检测工具Smartmontools安装、部署、使用
  5. 蒙特卡洛方法_基本理论-蒙特卡洛方法与定积分
  6. 系统架构师 项目经理 哪个更有前景_中央空调加地暖与五恒系统,哪个更省钱?...
  7. Java的三种代理模式完整源码分析
  8. 小米oj 反向位整数(简单位运算)
  9. 2016 10 26考试 NOIP模拟赛 杂题
  10. Android WebView和JavaScript交互