我们有一个高吞吐量应用程序,它将缓存的值存储在定期更新和读取的并发哈希映射中。每秒可能更新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导致了问题,但怎么会这样呢?我们没有做任何删除来排除丢失的条目。它完全是零星的,我无法找到它的底部。
任何想法都将不胜感激。
你说:
我的假设是同时调用put和get导致了问题,但怎么会这样呢?
所以您正在快速连续地在不同的线程上调用put
和get
?
如果是这样,则在安排执行get操作的线程时,put操作可能尚未完成。
要引用Javadoc的并发HashMap
:
检索操作(包括get
)通常不会阻塞,因此可能与更新操作(包括put
和删除
)重叠。检索反映了最近完成的更新操作在开始时保持的结果。
即使您可能认为您的get操作发生在您的put操作之后,但当跨线程操作时,您无法确定这一点。运行时跨线程的实际执行顺序是不可预测的。