我在一个HashMap上使用多个线程的.get(...)
,.put(...)
和.clear()
操作。 .put(...)
和.clear()
位于synchronized
块内,但.get(...)
不在。我无法想象这会导致问题,但在其他代码中我看到.get()
几乎总是同步的。
get / put的相关代码
Object value = map.get(key);
if(value == null) {
synchronized (map) {
value = map.get(key); // check again, might have been changed in between
if(value == null) {
map.put(key, new Value(...));
}
}
}
并且清楚只是:
synchronized (map) {
map.clear();
}
写操作将因同步而使缓存无效,get(...)
返回null或实例。我无法通过将.get(...)
操作放入synchronized(map)
块来确定可能出现的问题或改进措施。
答案 0 :(得分:3)
这是一个简单的场景,会在非同步get
上产生问题:
get
,计算哈希桶号,并获取抢占clear()
,因此分配较小的存储区数组这是一个更复杂的场景:
get
操作,计算哈希桶号,然后抢占put
,并意识到存储桶需要调整大小此时,A可能无法找到正确的项目,因为它很可能位于不同索引的哈希桶中。这就是为什么get
也需要同步的原因。