我们有一个高吞吐量的应用程序,它在 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 导致了问题,但怎么会这样呢?我们没有进行任何删除,以排除丢失的条目。这完全是零星的,我无法深究它。
如有任何想法,我们将不胜感激。
你说:
我的假设是同时调用 put 和 get 导致了问题,但怎么会这样呢?
所以你正在快速连续地在不同的线程上调用
put
和 get
?
如果是这样,则在计划执行 get 操作的线程时,put 操作可能尚未完成。
ConcurrentHashMap
:
检索操作(包括
)一般不会阻塞,因此可能与更新操作(包括get
和put
)重叠。检索反映了最近 completed 更新操作的结果。remove
即使您可能认为 get 操作发生在 put 操作之后,但在跨线程操作时您无法确定这一点。运行时跨线程的实际执行顺序是不可预测的。