在HashMap值对象上同步

AppX

我有一个关于Map内对象同步的问题(稍后我更改其值的相同对象)。我想自动读取,检查并可能对地图中的值进行更新,而无需锁定整个地图。这是处理对象同步的有效方法吗?

    private final Map<String, AtomicInteger> valueMap = new HashMap<>();

    public Response addValue(@NotNull String key, @NotNull Integer value) {
        AtomicInteger currentValue = valueMap.get(key);
        if (currentValue == null) {
            synchronized (valueMap) {
                // Doublecheck that value hasn't been changed before entering synchronized
                currentValue = valueMap.get(key);
                if (currentValue == null) {
                    currentValue = new AtomicInteger(0);
                    valueMap.put(key, currentValue);
                }
            }
        }
        synchronized (valueMap.get(key)) {
            // Check that value hasn't been changed when changing synchronized blocks
            currentValue = valueMap.get(key);
            if (currentValue.get() + value > MAX_LIMIT) {
                return OVERFLOW;
            }
            currentValue.addAndGet(value);
            return OK;
        }
    }
图库西

我没有看到您的方法与标准ConcurrentHashMap的方法有很大的不同-从ConcurrentHashMap经过大量测试的事实出发,可以将其配置为使用所需确切数量的线程来以最小的开销进行配置。

ConcurrentHashMap,你可以使用替代(K key, V old, V new)方法以原子更新keynew只有当old值没有改变。

由于消除了所有这些AtomicIntegers节省的空间,以及由于同步开销较低而节省的时间,可能会补偿必须将replace(k, old, new)调用包装在while循环内的情况:

ConcurrentHashMap<String, Integer> valueMap = 
      new ConcurrentHashMap<>(16, .75f, expectedConcurrentThreadCount);

public Response addToKey(@NotNull String key, @NotNull Integer value) {
     if (value > MAX_LIMIT) {
        // probably should set value to MAX_LIMIT-1 before failing
        return OVERFLOW; 
     }
     boolean updated = false;
     do {
        Integer old = putIfAbsent(key, value);
        if (old == null) {
             // it was absent, and now it has been updated to value: ok
             updated = true;
        } else if (old + value > MAX_LIMIT) {
             // probably should set value to MAX_LIMIT-1 before failing
             return OVERFLOW;
        } else {
             updated = valueMap.replace(key, old, old+value);
        }
     } while (! updated);

     return OK;
}

同样,从好的方面来说,即使在检查密钥后将其删除,此代码也可以工作(在这种情况下,您会抛出NPE)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在多个对象上同步

来自分类Dev

类对象上的同步

来自分类Dev

Java:在String对象上同步

来自分类Dev

如何使访问在Java HashMap中的值同步?

来自分类Dev

从HashMap值获取对象的属性

来自分类Dev

为什么要在小对象上同步?

来自分类Dev

为什么要在小对象上同步?

来自分类Dev

不同的线程在不同的对象上同步

来自分类Dev

在此对象和其他对象上同步

来自分类Dev

使用HashMap值从TreeSet中删除对象

来自分类Dev

可以总结HashMap中的对象值吗?

来自分类Dev

使用Lambda获取对象列表的hashmap值

来自分类Dev

如何访问HashMap中的对象中的值

来自分类Dev

显示存储在HashMap中的对象值

来自分类Dev

应该在列表本身还是在锁对象上同步?

来自分类Dev

例如,内部对象上的“已同步”。gameloop.player1

来自分类Dev

不同对象,不同线程上的同步方法

来自分类Dev

如何在Scrapy上同步获取请求的Response对象?

来自分类Dev

多线程访问同一对象上的同步方法和非同步方法

来自分类Dev

如何使用对象作为值构成HashMap,而对象又具有它自己的HashMap。爪哇

来自分类Dev

在二维网格上打印HashMap对象

来自分类Dev

JSP 将 hashmap 键与对象值进行比较

来自分类Dev

如何在HashMap中找到作为值的对象的字段?

来自分类Dev

同步HashMap与ConcurrentHashMap编写测试

来自分类Dev

同步HashMap与ConcurrentHashMap编写测试

来自分类Dev

从同步块返回同步值

来自分类Dev

HashMap上的多个键:它删除现有值吗?

来自分类Dev

对象上的C ++字段值未保留

来自分类Dev

在PHP对象动态属性上设置值