Нет, я не поняла вопрос. Речь шла о проверке того, что карта не содержит объект, перед ее созданием, а также о помещении его в карту и о том, что ее поток безопасен. Неважно, что делает новый Object (), он будет вызываться, только если объект не существует.
я есть кусок кода, который может быть выполнен несколькими потоками, который должен выполнить операцию ввода-вывода для инициализации общего ресурса, который хранится вConcurrentMap
, Мне нужно сделать этот поток кода безопасным и избежать ненужных вызовов для инициализации общего ресурса. Вот глючный код:
private ConcurrentMap<String, Resource> map;
// .....
String key = "somekey";
Resource resource;
if (map.containsKey(key)) {
resource = map.get(key);
} else {
resource = getResource(key); // I/O-bound, expensive operation
map.put(key, resource);
}
С помощью приведенного выше кода, несколько потоков могут проверитьConcurrentMap
и видите, что ресурса там нет, и все пытаются позвонитьgetResource()
что дорого Чтобы обеспечить только одну инициализацию общего ресурса и сделать код эффективным после инициализации ресурса, я хочу сделать что-то вроде этого:
String key = "somekey";
Resource resource;
if (!map.containsKey(key)) {
synchronized (map) {
if (!map.containsKey(key)) {
resource = getResource(key);
map.put(key, resource);
}
}
}
Это безопасная версия двойной проверки блокировки? Мне кажется, что поскольку чекиConcurrentMap
, он ведет себя как общий ресурс, который объявленvolatile
и, таким образом, предотвращает любые проблемы «частичной инициализации», которые могут возникнуть.