Im, использующий ConcurrentHashMap в многопоточной программе. Карта отображает ServerIDs на объекты, содержащие больше информации о сервере (независимо от того, онлайн-он или нет, сколько он использовался в последнее время и т. Д.). И ServerID, и ServerInformation неизменяемы.ConcurrentHashMap с неизменяемыми значениями - синхронизированная замена?
Чтобы обновить информацию о сервере я делаю более или менее то, что предлагается в качестве точки B) в этом вопросе: What is the preferred way to modify a value in 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'; вместо этого вы должны переделать вычисление: redo 'serverMap.get (id)' и redo 'addUsage'. –
Вы, конечно, правы! В противном случае замена, вероятно, никогда больше не сможет преуспеть ... Имеет ли смысл изменить мой вопрос, чтобы отразить ваше предложение? Извините, я новичок здесь ... –