我们有一个高吞吐量的应用程序,它将缓存的值存储在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,但立即再次调用它会返回正确的Object。对我来说这毫无意义。我的假设是同时调用put和get导致了这个问题,但这是怎么回事呢?我们不做任何删除,以便排除丢失的条目。这完全是零星的,我不能得到它的底部。
任何想法将不胜感激。
1条答案
按热度按时间oyxsuwqo1#
你说:
我的假设是同时调用put和get导致了这个问题,但这是怎么回事呢?
因此,您正在快速连续地在不同的线程上调用
put
和get
?如果是,则在获取操作的线程被调度用于执行时,放置操作可能尚未完成。
引用
ConcurrentHashMap
的Javadoc:检索操作(包括
get
)通常不会阻塞,因此可能与更新操作(包括put
和remove
)重叠。检索反映了最近 * 完成的 * 更新操作的结果,这些更新操作在开始时保持不变。即使你可能认为你的get操作发生在你的put操作之后,但当跨线程操作时,你不能确定这一点。运行时线程间的实际执行顺序是不可预测的。