AtomicInteger地图

bre*_*ish 7 java multithreading synchronization

我想实现一个共享对象来计算操作执行的统计信息.对象状态将由Map<String,AtomicInteger>(键是操作名称,值是操作执行的次数)表示.我是否正确我可以选择一个HashMap<String,AtomicInteger>实现并且不使用它来从中获取值,因为AtomicInteger value下面有一个volatile 字段.

执行统计数据添加和增加的代码示例:

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();
}

}
Run Code Online (Sandbox Code Playgroud)

cla*_*laj 5

如果要确保计数器初始化方面的线程安全,则应使用a ConcurrentHashMap并始终实例化并增加计数器,方法是:

themap.putIfAbsent("the name", new AtomicInteger(0)); 
themap.get("the name").incrementAndGet();
Run Code Online (Sandbox Code Playgroud)

您还可以确保在开始之前初始化所有使用的计数器,并使用所需的任何集合。一个普通的AtomicInteger[]-array是目前为止最快的,因为你知道去哪里找,HashTable可能会稍微快于HashMap

如果您事先知道拥有哪些计数器,则还可以定义enum所有计数器名称的java 并使用EnumMap<YourCountersEnum, AtomicInteger>。这可能会使查询性能接近AtomicInteger[]-array查询。

  • @Voo不!如果这样做,则第一次初始化计数器时得到2。您始终总是通过crementAndAndGet无条件地对其进行增量,但是如果它们为null,则会创建它们。“空==零”。也咬我 (3认同)