奇怪的 ConcurrentHashMap 行为

问题描述 投票:0回答:1

我们有一个高吞吐量的应用程序,它在 ConcurrentHashMap 中存储缓存值,并定期更新和读取。可能每秒更新 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,但立即再次调用它会返回正确的对象。对我来说这没有意义。我的假设是同时调用 put 和 get 导致了问题,但怎么会这样呢?我们没有进行任何删除,以排除丢失的条目。这完全是零星的,我无法深究它。

如有任何想法,我们将不胜感激。

java thread-safety concurrenthashmap
1个回答
0
投票

你说:

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

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

put
get

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

引用 Javadoc

ConcurrentHashMap

检索操作(包括

get
)一般不会阻塞,因此可能与更新操作(包括
put
remove
)重叠。检索反映了最近 completed 更新操作的结果。

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

© www.soinside.com 2019 - 2024. All rights reserved.