Я использую ConcurrentHashMap в многопоточной программе. Карта сопоставляет идентификаторы ServerID с объектами, содержащими дополнительную информацию о сервере (находится ли он в сети или нет, как часто он использовался в последнее время и т. Д.). И ServerID, и ServerInformation неизменны.
Чтобы обновить информацию о сервере, я делаю более или менее то, что предлагается в пункте B) в этом вопросе: Каков предпочтительный способ изменения значения в ConcurrentHashMap?
а именно (изменено для использования моих собственных имен переменных) это:
public void addUsage(ServerID id, long moreUsage) {
ServerInfo oldInfo = serverMap.get(id);
ServerInfo newInfo = oldInfo.addUsage(moreUsage);
serverMap.put(id, newInfo);
}
Теперь мой вопрос: не следует ли синхронизировать этот метод, чтобы исключить возможность потери обновлений?
Или есть другой способ добиться этого? Может быть, что-то вроде следующего (отредактировано из моей исходной версии, чтобы удалить очевидную ошибку):
public void addUsage(ServerID id, long moreUsage) {
ServerInfo oldInfo = serverMap.get(id);
ServerInfo newInfo = oldInfo.addUsage(moreUsage);
while (!serverMap.replace(id, oldInfo, newInfo) ) {
oldInfo = serverMap.get(id);
newInfo = oldInfo.addUsage(moreUsage);
// try again later
Thread.sleep(SOME_TIME);
};
}
Thread.sleep
- неправильный ответ на неудачныйreplace
; вместо этого вы должны повторить вычисление: повторитьserverMap.get(id)
и повторитьaddUsage
. - person Louis Wasserman   schedule 09.11.2013