Несколько ответов на SO упоминают, что метод get в HashMap может попасть в бесконечный цикл (например, этот или этот), если не синхронизирован должным образом (и, как правило, в нижней строке "не используйте HashMap в многопоточной среде, используйте ConcurrentHashMap" ).
Хотя я могу легко понять, почему одновременные вызовы метода HashMap.put(Object) могут вызвать бесконечный цикл, я не могу понять, почему метод get (Object) может застрять, когда он пытается прочитать HashMap, что в этот момент изменяется. Я рассмотрел реализацию в openjdk и содержит цикл, но условие выхода e != null
должно быть выполнено рано или поздно. Как он может зависеть навсегда?
Кусок кода, который явно упоминается, чтобы быть уязвимым для этой проблемы:
public class MyCache {
private Map<String,Object> map = new HashMap<String,Object>();
public synchronized void put(String key, Object value){
map.put(key,value);
}
public Object get(String key){
// can cause in an infinite loop in some JDKs!!
return map.get(key);
}
}
Может кто-нибудь объяснить, как поток, помещающий объект в HashMap, и другое чтение из него может чередоваться таким образом, что генерируется бесконечный цикл? Это связано с некоторой проблемой когерентности кеша или переупорядочением команд процессора (поэтому проблема может возникнуть только на многопроцессорной машине)?