【发布时间】:2015-06-10 02:22:47
【问题描述】:
对于具有以下要求的高性能并发收集,什么是合适的候选者:
- 集合中的元素数量很少(少数元素,通常少于 10 个)并且很少更改。
- 主要用例是遍历元素。这种情况经常发生,而且必须非常快(即应该是无锁的)。
- 有时会使用迭代器 remove() 方法删除元素。这最好也工作得非常快(但它不如迭代器 next() 方法重要)。
- 元素的顺序无关紧要,因此元素如何插入到集合中并不重要。
- 最好来自标准 Java 库。
我考虑过为此使用 ConcurrentLinkedQueue,但如果您从不调用 poll() 方法,就会发现它会泄漏内存(按设计)。我不确定情况是否仍然如此(提到这一点的帖子是从 ~ 2011 年开始的,我发现一些提到这可能已经解决)。
我也考虑过ConcurrentSkipListSet,但不确定排序对性能有什么影响(因为我不关心顺序)。
【问题讨论】:
-
如果您的主要用例是查找元素,HashMap 将是最好的。至于 CopyOnWriteArrayList,如 javadoc:不支持对迭代器本身的元素更改操作(删除、设置和添加)。这些方法抛出 UnsupportedOperationException。
-
除了使用不支持的迭代器删除元素外, CopyOnWriteArrayList 在我看来就像您要查找的内容。即使在迭代期间,您仍然可以直接调用列表的 remove() 方法。但是你不能保证你正在删除正确的元素。您是否尝试过简单地在 ArrayList 上进行同步?你证明它不够快吗?
-
+1 到 CopyOnWriteArrayList,提供“少量元素”和“很少更改”是您可以做出的假设。如果他们不是——例如,如果恶意用户可以导致有很多元素和频繁更新——那么我会避免它,因为所述恶意用户可以进行 DOS 风格的攻击(创建一个列表包含数千个元素,然后频繁地从中添加和删除元素,每个操作都是 O(n))。
-
ConcurrentHashMap 应该提供良好的性能,特别是如果您将optimal init params 用于您的用例。
-
@JFPicard 的主要用例是遍历元素并对每个元素执行操作——而不是查找特定元素。
标签: java performance data-structures collections concurrency