提问者:小点点

奇怪的并发HashMap行为


我们有一个高吞吐量应用程序,它将缓存的值存储在定期更新和读取的并发哈希映射中。每秒可能更新100次。

以下面的例子为例:

Map<Long, Object> map= new ConcurrentHashMap<>();

......

public void updateValue(Long key, Object value) {
    map.put(key, value);
}

public Object readValue(Long key) {
    return map.get(key);
}

......

Object val = readValue(key); //Works the majority of the time but can return null even though previous calls returned a value
if (val == null) {
    val = readValue(key); // This works
}    

通常情况下,调用readValue会导致返回null,但立即再次调用它会返回正确的Object。对我来说,这没有意义。我的假设是同时调用put和get导致了问题,但怎么会这样呢?我们没有做任何删除来排除丢失的条目。它完全是零星的,我无法找到它的底部。

任何想法都将不胜感激。


共1个答案

匿名用户

你说:

我的假设是同时调用put和get导致了问题,但怎么会这样呢?

所以您正在快速连续地在不同的线程上调用putget

如果是这样,则在安排执行get操作的线程时,put操作可能尚未完成。

要引用Javadoc的并发HashMap

检索操作(包括get)通常不会阻塞,因此可能与更新操作(包括put删除)重叠。检索反映了最近完成的更新操作在开始时保持的结果。

即使您可能认为您的get操作发生在您的put操作之后,但当跨线程操作时,您无法确定这一点。运行时跨线程的实际执行顺序是不可预测的。