java - AtomicLongMap 读取线程安全

标签 java synchronization thread-safety

我有以下类(class):

public class Storage {
    protected static final AtomicLongMap<String> MAP;
    protected Storage () {
                MAP= AtomicLongMap.create();
    }

    public void decrement(String id) {
        long num = MAP.get(id);
        if (num  != 0) {
            MAP.decrementAndGet(id);
        }
    }

    public void putIntoActiveAgents(String id, Integer num) {
        MAP.put(id, num);
    }

    public void remove(String id) {
        MAP.remove(id);
    }

    public Long get(String id) {
        return MAP.get(ID);
    }
}

就我而言,我假设有 6 个线程正在执行类似的操作: 每个线程检查map中的long是否等于1,如果不等于1,则调用decrement,如果是,则调用remove。 我到处都读到 AtomicLongMap 是线程安全的。我确信,当有人递增/递减长数字时,但我不确定当其他线程从该映射中读取值时它是否仍然是线程安全的。我的场景: 1. 线程 A 从映射中读取值 - 它是 2(因此它递减该值) 2. 线程 B 在计数器递减之前读取值 - 它仍然返回 2,因此它也会递减值。 3. 结果,没有人看到设置为 1 的值。

我的问题是在这种情况下,我需要同步MAP吗?

最佳答案

如果您使用的是 Java 8,查看您的代码,我建议您使用 ConcurrentHashMap。 Java 8 中的 Map 接口(interface)已更新为新函数,例如computeIfPresent()。所以你的函数“decrement(String id)”看起来像这样 -

public class Storage {
    protected static final Map<String, Long> MAP = new ConcurrentHashMap<>();

    public void decrement(String id) {
        MAP.computeIfPresent(id, (id, currentValue) -> --currentValue);
    }

    public void putIntoActiveAgents(String id, Integer num) {
        MAP.put(id, num);
    }

    public void remove(String id) {
        MAP.remove(id);
    }

    public Long get(String id) {
        return MAP.get(ID);
    }
}

关于java - AtomicLongMap 读取线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38957175/

相关文章:

multithreading - 如何在不等待的情况下从 channel 获取值

java - 在java中使用synchronized block 同时阻止对多个方法的访问

scala - Scala 中仅更新单个 var 线程的类实例安全吗?

c++ - 删除对象时清理引用对象的线程(在 C++ 中)

java - 使用代理连接数据源

java - 复制构造函数和防御性复制

java - 如何使用Hibernate批处理

java - 从同一 jar 中存在的 java 代码读取 jar 中的文件

c# - 两个线程上交错进程

c++ - 为什么c++ std::hash会创建一个仿函数结构体并且可以在每次不创建结构体的情况下调用它