非常简单:除了 ConcurrentDictionary (如果必须的话我会使用它,但这不是真正正确的概念),是否有任何并发集合(IPrducerConsumer 实现)支持基于项目或谓词的简单相等性删除特定项目定义删除条件?
说明:我有一个多线程、多阶段工作流算法,它从数据库中提取对象并将它们放入“启动”队列中。从那里,它们被下一阶段抓取,进一步处理,并塞入其他队列。这个过程还要经历几个阶段。同时,第一阶段由其主管再次调用,并将对象从数据库中提取出来,这些对象可以包括仍在处理中的对象(因为它们尚未完成处理,因此尚未重新保留标记集:他们完成了)。
我正在设计的解决方案是一个“工作中”的大师系列;当第一阶段检索对象进行处理时,对象会进入该队列,并在工作流的任何阶段完成必要的处理后将其重新保存到数据库中作为“已处理”后删除。当该对象位于该列表中时,如果第一阶段重新检索该对象,它将被忽略。
我本来计划使用 ConcurrentBag,但唯一的删除方法 (TryTake) 会从包中删除任意项目,而不是指定的项目(ConcurrentBag 是slow在.NET 4)中。 ConcurrentQueue 和 ConcurrentStack 也不允许删除除下一个项目之外的其他项目,留下 ConcurrentDictionary,它可以工作,但超出了我的需要(我真正需要的是存储正在处理的记录的 Id;它们在工作流程中不会改变)。
之所以没有这样的数据结构是因为所有集合的查找操作时间为O(n)
。这些都是IndexOf
, Remove(element)
等等。他们都枚举所有元素并检查它们是否相等。
只有哈希表的查找时间为 O(1)。在并发场景中,O(n) 查找时间将导致集合的锁定时间很长。其他线程在此期间将无法添加元素。
在字典中,只有被哈希命中的单元格才会被锁定。当一个线程通过散列单元中的元素检查相等性时,其他线程可以继续添加。
我的建议是继续使用 ConcurrentDictionary。
顺便说一句,您是对的,ConcurrentDictionary 对于您的解决方案来说有点过大。您真正需要的是快速检查对象是否正在工作。 AHashSet
将是一个完美的选择。那么它基本上什么也不做Add(element)
, Contains(element)
, Remove(element)
。有一个ConcurrentHeshSet
在java中的实现。对于 c# 我发现了这个:如何在.Net中实现ConcurrentHashSet https://stackoverflow.com/questions/4306936/how-to-implement-concurrenthashset-in-net不知道有多好。
作为第一步,我仍然会编写一个包装器HashSet
接口周围ConcurrentDictionary
启动并运行它,然后尝试不同的实现并查看性能差异。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)