我想实现一个共享对象来计算操作执行的统计信息。
对象状态将由Map<String,AtomicInteger>
表示(键是操作名称,值是操作执行的次数)。我是否正确我可以选择HashMap<String,AtomicInteger>
实现,并且不使用同步来获取它的值,因为AtomicInteger下面有一个不稳定的value
字段。
执行统计信息的添加和增加的代码示例:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
public final class Stats {
private final Map<String, AtomicInteger> statistics = new HashMap<String, AtomicInteger>();
public int increment(String operationName) {
if (!statistics.containsKey(operationName)) {
synchronized (statistics) {
if (!statistics.containsKey(operationName))
statistics.put(operationName, new AtomicInteger(0));
}
}
return statistics.get(operationName).getAndIncrement();
}
public int getOpStats(String operationName) {
if (!statistics.containsKey(operationName)) {
return 0;
}
return statistics.get(operationName).get();
}
}
答案 0 :(得分:5)
如果你想在计数器初始化方面保持线程安全,你应该使用ConcurrentHashMap
并始终以这种方式实现并增加计数器:
themap.putIfAbsent("the name", new AtomicInteger(0));
themap.get("the name").incrementAndGet();
您还可以确保在开始之前初始化所有使用的计数器,并且只使用您喜欢的任何集合。一个简单的AtomicInteger[]
- 数组是最快的,因为你知道在哪里看,HashTable
可能比HashMap
略快。
如果事先知道您拥有哪些计数器,您还可以定义所有计数器名称的java enum
并使用EnumMap<YourCountersEnum, AtomicInteger>
。这可能会使查找性能接近AtomicInteger[]
- 数组查找。