java - 从多个线程填充 map

标签 java multithreading guava concurrenthashmap

我有一个从多个线程填充的 ConcurrentHashMap,如下所示:

private static Map<ErrorData, Long> holder = new ConcurrentHashMap<ErrorData, Long>();

public static void addError(ErrorData error) {
    if (holder.keySet().contains(error)) {
        holder.put(error, holder.get(error) + 1);
    } else {
        holder.put(error, 1L);
    }
}

上面的代码中是否存在竞争条件的可能性并且它可以跳过更新?还有我如何使用 Guava AtomicLongMap在这里是否可以提供更好的性能?

我正在使用 Java 7。

最佳答案

是的,存在竞争的可能性,因为您没有检查包含和原子放置。

您可以按如下方式使用 AtomicLongMap,它以原子方式执行此检查:

private static final AtomicLongMap<ErrorData> holder = AtomicLongMap.create();

public static void addError(ErrorData error) {
  holder.getAndIncrement(error);
}

如 javadoc 中所述:

[T]he typical mechanism for writing to this map is addAndGet(K, long), which adds a long to the value currently associated with K. If a key has not yet been associated with a value, its implicit value is zero.

All operations are atomic unless otherwise noted.

关于java - 从多个线程填充 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34405222/

相关文章:

multithreading - 重新启动在整个应用程序生命周期中存在的 Delphi TThread

scala - 构建自动化 - sbt : Compile/Test against multiple dependencies

java - JAX-RS:每个资源的选项

java - 大十进制除法

c++ - 从不同线程写入 boost::asio 套接字

java - 多线程中的 AES+HMAC 加密 - Java

java - 如何在谷歌 Guava 事件总线中处理具有相同参数的多个监听器

guava - EventBus google guava 关闭 Hook

java - JUnit:为测试类设置事务边界

java - 无法加载请求的类: org. hibernate.MySQL5InnoDBDialect