2013-06-23 55 views
1

在java中,我需要计算每个键的项目,所以我想用ConcurrentMap键和价值有AtomicInteger但是我不知道是否有更好的方法。它不是一个关键的服务,它只是用来收集统计数据,所以我不介意如果我迟到了10秒,并且有正确的数据或者类似的东西。所以我想知道在标准的java并发中是否有更好的做法,或者我是否再次用自己处理ConcurrentMap和AtomicInteger(一个可以解决问题的例子也许是消息传递,如果是的话能够帮助我吗?)(最好是用例子......)一些不会有性能问题的东西,并且也是安全的,并且易于使用,我不介意延迟。在java中每个键的计数最佳做法是什么

回答

4

番石榴提供了ConcurrentHashMultiset。这是一个并发的Multiset实现,它实际上是一个允许重复的集合。像往常一样,您可以add(E)remove(Object),但也可以检索Multiset中元素的count(Object)

其实this is implemented使用的是支持ConcurrentHashMap<E, AtomicInteger>,所以你的练习完全没问题。但是:

  • Multiset接口提供更好的抽象,它甚至延伸Collection
  • 正确管理这些AtomicIntegers你自己是一件棘手的事情。快速浏览番石榴的代码应该能够让您了解并发编程带来的挑战:您需要大量的compareAndSet s和无限的while循环来确保正确的结果出来。
+0

听起来很完美。我按照你的建议看待实现,实际上它不是微不足道的。所以如果我添加10个类型的苹果项目,它不会存储10个项目,因为它的一套只会计算它苹果为10,对不对? – Jas

+0

@Jason Yup,它在地图上只有一个包含'AtomicInteger'且值为'10'的'Apple'的条目。好处是你不必再考虑它了,所有这些都被抽象出来了,你可以使用'Multiset'接口来处理它。 –

+0

谢谢,就像我看到的旁注有关于它的表现的讨论。 https://groups.google.com/forum/#!topic/guava-discuss/KJuv1P77vRI – Jas

0

是的,我认为这是正确的方向,所以我真的不明白为什么你认为这不容易。只需使用并发地图特定功能。即更新统计将为:

AtomicInteger newCounter = new AtomicInteger(1); 
AtomicInteger existingCounter = map.putIfAbsent(key, newCounter); 
if(existingCounter != null) 
    existingCounter.incrementAndGet(); 
相关问题