java - 如何使用 ConcurrentHashMap 执行线程安全的获取然后删除?

标签 java concurrenthashmap

在一次采访中,我被要求检查以下代码是否按预期工作。

ConcurrentHashMap<Integer, Integer> chm = new ConcurrentHashMap<>();

if (chm.get(key) != null) {
    chm.get(key).doSomething();
    chm.remove(key);
}

根据 JavaDocs,get 返回最后完成的更新操作的值。因此,如果线程 1 已经调用了 chm.remove(key) 并且如果线程 2 进入了 if 语句并且即将调用 get 方法,那么我们可能会得到一个异常。这是正确的吗?

我怎样才能使这个线程安全?

最佳答案

Map.remove(key) 返回值,如果它已被删除。这在很多情况下都是一个非常好的技巧,包括您的情况:

Object value = chm.remove(key)
if(value != null)
{
     value.doSomething();
}

你不能安全地使用 get 然后 remove,因为如果两个线程同时调用你的方法,那么在 key 完成之前,它们总是有调用 doSomething 两次或更多次的风险已被删除。

如果先删除它,这是不可能的。上面的代码是线程安全的,也更简单。

关于java - 如何使用 ConcurrentHashMap 执行线程安全的获取然后删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34346869/

相关文章:

带有反射的 java.lang.SecurityException

java - 如何使用检测打印 Java 运行时调用的所有方法?

java - Concurrent HashMap merge() 和 put() 的区别

java - 无法解析/无法解析为类型

java - 下载目录下写问题

java - 如何实现与LinkedHashMap类似的ConcurrentHashMap?

java - 跟踪 map 中队列之间的进度

java - ConcurrentHashMap jdk 8 使用 TreeNodes 而不是 List .. 为什么?

java - 使用redis缓存java对象: why it should be better than a ConcurrentHashMap?

java - 通过父类(super class)返回与类名相同的数据类型?