以原子方式递增存储在 ConcurrentHashMap 中的计数器 [英] Atomically incrementing counters stored in ConcurrentHashMap

查看:23
本文介绍了以原子方式递增存储在 ConcurrentHashMap 中的计数器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从网络应用程序的各个位置收集一些指标.为简单起见,所有这些都将是计数器,因此唯一的修饰符操作是将它们加 1.

I would like to collect some metrics from various places in a web app. To keep it simple, all these will be counters and therefore the only modifier operation is to increment them by 1.

增量将是并发的并且经常发生.读取(转储统计数据)是一种罕见的操作.

The increments will be concurrent and often. The reads (dumping the stats) is a rare operation.

我想使用 ConcurrentHashMap.问题是如何正确递增计数器.由于地图没有增量"操作,我需要先读取当前值,将其增量而不是将新值放入地图中.没有更多代码,这不是原子操作.

I was thinking to use a ConcurrentHashMap. The issue is how to increment the counters correctly. Since the map doesn't have an "increment" operation, I need to read the current value first, increment it than put the new value in the map. Without more code, this is not an atomic operation.

是否有可能在没有同步的情况下实现这一点(这会破坏 ConcurrentHashMap 的目的)?我需要查看 Guava 吗?

Is it possible to achieve this without synchronization (which would defeat the purpose of the ConcurrentHashMap)? Do I need to look at Guava ?

感谢您的指点.

附言
有一个关于 SO 的相关问题(最有效的方法在 Java 中增加一个 Map 值)但专注于性能而不是多线程

P.S.
There is a related question on SO (Most efficient way to increment a Map value in Java) but focused on performance and not multi-threading

更新
对于那些通过搜索同一主题到达这里的人:除了下面的答案,还有一个有用的 presentation 顺便涵盖了相同的主题.见幻灯片 24-33.

UPDATE
For those arriving here through searches on the same topic: besides the answers below, there's a useful presentation which incidentally covers the same topic. See slides 24-33.

推荐答案

在 Java 8 中:

In Java 8:

ConcurrentHashMap<String, LongAdder> map = new ConcurrentHashMap<>();

map.computeIfAbsent("key", k -> new LongAdder()).increment();

这篇关于以原子方式递增存储在 ConcurrentHashMap 中的计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆