简体   繁体   English

在java中计算每个键的最佳实践是什么?

[英]what is the best practice for counting per key in java

In java I need to count items per key so i thought of using ConcurrentMap with key and as value to have AtomicInteger however I wonder if there is a better way. 在java中,我需要计算每个键的项目,所以我想使用带键的ConcurrentMap和作为值来使用AtomicInteger但是我想知道是否有更好的方法。 Its not a critical service, its just used for collecting stats, so i don't mind if i'm late 10 seconds with correct stats or something like this. 它不是一个关键的服务,它只是用于收集统计数据,所以我不介意我是否有10秒正确的统计数据或类似的东西。 So i wonder if there is a better practice for it in standard java concurrency, or whether i'm left again with dealing by myself with ConcurrentMap and with AtomicInteger (an example which could also solve the problem would be message passing maybe, if yes how could that help me?) (best would be with example...) something which would not have performance issues and would be safe as well, and easy to use, i don't mind about latency. 所以我想知道在标准的Java并发中是否有更好的实践,或者我是否再次使用ConcurrentMap和AtomicInteger (一个也可以解决问题的例子可能是消息传递,如果是的话可以帮助我吗?)(最好用例子......)一些不会出现性能问题而且安全性也好,并且易于使用的东西,我不介意延迟。

Guava provides a ConcurrentHashMultiset . Guava提供了ConcurrentHashMultiset This is a concurrent Multiset implementation, which is effectively a set allowing duplicates. 这是一个并发的Multiset实现,它实际上是一个允许重复的集合。 You can add(E) and remove(Object) as usual, but also retrieve the count(Object) of an element in the Multiset . 您可以像往常一样add(E)remove(Object) ,但也可以检索Multiset元素的count(Object)

In fact, this is implemented using a backing ConcurrentHashMap<E, AtomicInteger> , so your practice is perfectly fine. 事实上, 这是使用支持ConcurrentHashMap<E, AtomicInteger> ,所以你的练习完全没问题。 However: 然而:

  • The Multiset interface provides a nicer abstraction, it even extends Collection . Multiset接口提供了更好的抽象,它甚至扩展了Collection
  • Properly managing those AtomicIntegers yourself is a tricky business. 正确地管理这些AtomicIntegers是一件棘手的事情。 Quickly glancing over Guava's code should give you an idea of the challenges that concurrent programming imposes: you need lots of compareAndSet s and infinite while loops to make sure the correct results come out. 快速浏览一下Guava的代码应该让你了解并发编程所带来的挑战:你需要大量的compareAndSet和无限的while循环来确保正确的结果出来。

Yes, I think it is right direction, so I really don't understand why do you think it is not easy. 是的,我认为这是正确的方向,所以我真的不明白你为什么认为这不容易。 Just use concurrent-map specific functions. 只需使用并发映射特定功能。 Ie to update statistics will be: 即更新统计数据将是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM