Как корректно обновить значение в ConcurrentHashMap в многопоточной среде
У меня есть довольно простой класс, который собирает статистику по статусам.
public class Status {
private ConcurrentMap<String, AtomicInteger> statusesMap = new ConcurrentHashMap<>();
public void addStatus(String status) {
if (statusesMap.containsKey(status)) {
statusesMap.get(status).getAndIncrement();
} else {
statusesMap.put(status, new AtomicInteger(1));
}
}
}
Очевидно, что при обращении к методу addStatus из нескольких потоков в результате в мапе будет неверное значение. Делать полностью метод синхронным не хотелось бы - это лишняя нагрузка. Можно ли код как-то преобразовать? Например на writeReadLock?
Попробовала и computeIfAbsent и compute. Но метод computeIfAbsent, судя по всему, имеет проблему с блокировками для java8. У compute наблюдала аналогичное поведение. Пока решением видится
AtomicLong result = statusesMap.get(status);
if (result != null) {
result.getAndIncrement();
} else {
statusesMap.computeIfAbsent(status, t -> new AtomicLong()).getAndIncrement();
}