我有需要每秒更新一次的集合。我用于ScheduledExecutorService。但我有疑问,最好是给线程池完整集合还是将每个集合元素发送到线程池?
答案 0 :(得分:0)
我建议采用以下解决方案:
Map
个集合,请将其替换为ConcurrentHashMap
。此map
允许迭代器容忍集合更改,并且基于键hashCode()
对其进行锁定。Set
个集合,请使用工厂Collections.newSetFromMap()
创建的集合,并将ConcurrentHashMap
个实例作为参数传递。这将为您提供set
与我上面提到的map
相同的线程安全相关属性。对于List
个集合,首先要考虑您是否真的需要List
。如果是,请考虑使用CopyOnWriteArrayList
或使用
List list = Collections.synchronizedList(new ArrayList()); //或者也许是LinkedList,但这与问题无关。
请注意,此包装列表返回的迭代器不是线程安全的,可能会抛出ConcurrentModificationException
。
现在,您可能会遇到问题 - 工厂返回的Set
,其中的值不能相同。如果这对您来说是个问题,请尝试使用一些Guava Multiset
。有关它的更多信息可以在here找到。
好的,我们完成了收藏。现在,让我们考虑ConcurrentHashMap
。
此结构的实现为您提供所谓的最终可见性保证。这意味着每个迭代器代表一些集合状态 - 可能不是最后一个,但状态保证在某个时刻有效,也许在过去。通常这对大多数情况来说已经足够了。
这意味着要并行处理某些活动,您可以将对此集合的引用传递给修改它的Thread
或Runnable
,以及其他Thread
或{{ 1}}读它,你应该没事。
请注意,上面提到的Runnable
的吞吐量会更低,因为此集合是由于该包装器添加的List
块而被独占访问。