У меня вопрос о синхронизации объектов внутри Карты (те же объекты, которые я позже меняю). Я хочу, чтобы атомарно читал, делал проверки и, возможно, обновлял значение с карты без блокировки всей карты. Является ли это действенным способом работы с синхронизацией объектов?Синхронизированный объект объекта HashMap
private final Map<String, AtomicInteger> valueMap = new HashMap<>();
public Response addValue(@NotNull String key, @NotNull Integer value) {
AtomicInteger currentValue = valueMap.get(key);
if (currentValue == null) {
synchronized (valueMap) {
// Doublecheck that value hasn't been changed before entering synchronized
currentValue = valueMap.get(key);
if (currentValue == null) {
currentValue = new AtomicInteger(0);
valueMap.put(key, currentValue);
}
}
}
synchronized (valueMap.get(key)) {
// Check that value hasn't been changed when changing synchronized blocks
currentValue = valueMap.get(key);
if (currentValue.get() + value > MAX_LIMIT) {
return OVERFLOW;
}
currentValue.addAndGet(value);
return OK;
}
}
Вы также можете использовать 'ConcurrentHashMap' или' Collections.synchronizedMap (map) '(см. [Этот вопрос] (http://stackoverflow.com/questions/510632/whats-the-difference-between-concurrenthashmap-and -collections-synchronizedmap)) для синхронизации вашей карты. – NiziL
Как вы гарантируете, что значение не изменилось между проверкой get + до обновления/возврата в ConcurrentHashMap, например. Он должен работать для обновления, так как у вас будет сохранено и проверено предыдущее значение при обновлении, но при возврате OVERFLOW должна быть возможность изменения значения перед возвратом, если вы не заблокируете доступ между проверкой и возвратом? – AppX
В вашем коде мне не ясно, что 'currentValue' не будет сохранять устаревшее значение, если доступ к' valueMap' будет выполняться без синхронизации (как вы это сделали). – scottb