【发布时间】:2016-12-05 20:59:37
【问题描述】:
我正在使用increment 和decrement 指标的以下类来测量我的应用程序指标。
public class AppMetrics {
private final AtomicLongMap<String> metricCounter = AtomicLongMap.create();
private static class Holder {
private static final AppMetrics INSTANCE = new AppMetrics();
}
public static AppMetrics getInstance() {
return Holder.INSTANCE;
}
private AppMetrics() {}
public void increment(String name) {
metricCounter.getAndIncrement(name);
}
public AtomicLongMap<String> getMetricCounter() {
return metricCounter;
}
}
我正在从多线程代码中调用AppMetrics 类的increment 方法,以通过传递指标名称来增加指标。
问题陈述:
现在我想为每个clientId 拥有metricCounter,这是一个字符串。这意味着我们也可以多次获得相同的clientId,有时它会是一个新的clientId,因此我需要为该clientId 提取metricCounter 映射并在该特定映射上增加指标(即我不知道该怎么做)。
记住它必须是线程安全的并且必须执行原子操作的正确方法是什么。我正在考虑制作这样的地图:
private final Map<String, AtomicLongMap<String>> clientIdMetricCounterHolder = Maps.newConcurrentMap();
这是正确的方法吗?如果是,那么我如何通过传递 clientId 作为键来填充此映射,它的值将是每个指标的计数器映射。
我使用的是 Java 7。
【问题讨论】:
-
使用 computeIfAbsent(): docs.oracle.com/javase/8/docs/api/java/util/concurrent/…
-
哎呀,我在使用 Java 7。抱歉忘了提。
-
使用并发映射是一个好的开始,但确保更新是原子的则比较棘手,尤其是如果您不在 Java 8 上。
-
切换到 Java 8 :-) 说真的,你应该。尽快。
-
如果争用不是主要问题,您可能需要考虑传统锁定而不是并发集合。
标签: java multithreading concurrency thread-safety guava