AtomicLongMap 与 ConcurrentHashMultiset

AtomicLongMap vs. ConcurrentHashMultiset

来自 AtomicLongMap 的文档:

Note: If your values are always positive and less than 2^31, you may wish to use a Multiset such as ConcurrentHashMultiset instead. Warning: Unlike Multiset, entries whose values are zero are not automatically removed from the map. Instead they must be removed manually with removeAllZeros().

它表明您可能希望使用 Multiset。我的问题是,Multiset 比 AtomicLongMap 有什么好处?选择仅包含正值的映射时应考虑哪些因素?使用 Multiset 的唯一原因是我不需要手动调用 removeAllZeros() 吗?

Multiset 在概念上是不同的。首先,它是一个 Collection,所以它可以用作集合,而 AtomicLongMap 不是集合(也不是地图)。多重集表示一组可能重复的元素,要对它们的计数执行数学运算,您可以添加或删除元素。 AtomicLongMap 方法名称与 AtomicLong class 更一致,并明确假定您正在对值执行数学运算。一种或另一种实现可能不支持某些操作。例如,AtomicLongMap 中有 addAndGetgetAndAdd 操作,但 Multiset 只有 add 方法,其工作方式类似于 getAndAdd.

因此,虽然在许多情况下这些 class 是可以互换的,但如果您将数据视为可能重复元素的集合,请使用 ConcurrentHashMultiset。如果您将数据视为键和 long 值之间的映射,请使用 AtomicLongMap

请注意,自 Java-8 起,这些 class 可以轻松替换为标准 JDK ConcurrentHashMap<K, Long>。例如,您可以使用 map.merge(key, 1L, Long::sum); 来递增映射值。