java - 在删除条目时迭代 ConcurrentHashMap

标签 java multithreading concurrenthashmap

我想在删除条目时定期迭代 ConcurrentHashMap,如下所示:

for (Iterator<Entry<Integer, Integer>> iter = map.entrySet().iterator(); iter.hasNext(); ) {
    Entry<Integer, Integer> entry = iter.next();
    // do something
    iter.remove();
}

问题是在我迭代时另一个线程可能正在更新或修改值。如果发生这种情况,这些更新可能会永远丢失,因为我的线程在迭代时只会看到陈旧的值,但 remove() 将删除 Activity 条目。

经过一番考虑,我想到了这个解决方法:

map.forEach((key, value) -> {
    // delete if value is up to date, otherwise leave for next round
    if (map.remove(key, value)) {
        // do something
    }
});

这样做的一个问题是,它不会捕获对未实现 equals()(例如 AtomicInteger)的可变值的修改。有没有更好的方法来安全删除并发修改?

最佳答案

您的解决方法可行,但存在一种可能的情况。如果某些条目不断更新,则 map.remove(key,value) 在更新结束之前可能永远不会返回 true。

如果你使用JDK8,这里是我的解决方案

for (Iterator<Entry<Integer, Integer>> iter = map.entrySet().iterator(); iter.hasNext(); ) {
    Entry<Integer, Integer> entry = iter.next();
    Map.compute(entry.getKey(), (k, v) -> f(v));
    //do something for prevValue
}
....
private Integer prevValue;

private Integer f(Integer v){
    prevValue = v;
    return null;
}

compute() 会将 f(v) 应用于值,在我们的例子中,将值分配给全局变量并删除条目。

根据 Javadoc,它是原子的。

Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). The entire method invocation is performed atomically. Some attempted update operations on this map by other threads may be blocked while computation is in progress, so the computation should be short and simple, and must not attempt to update any other mappings of this Map.

关于java - 在删除条目时迭代 ConcurrentHashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37127285/

相关文章:

java - 如何使 Google Drive Java SDK 读取/写入 "my Drive"而不是其他地方?

java - Android 应用程序单击按钮调用不正确的 OnClick 监听器

objective-c - 如何允许用户在不暂停应用程序更新循环的情况下调整 NSSlider?

java - 最小值并发映射

java - ConcurrentHashMap 是否需要包装在同步块(synchronized block)中?

java - Apache Camel 每天安排多次

Java JACOB 检索给定 Win32_* 类对象的所有属性

java - 这些方法是线程安全的吗?

multithreading - 增量数字表 postgresql 线程安全

java - 按值过滤 ConcurrentHashMap