Я хочу, чтобы как computeIfPresent и putIfAbsent в одной атомарной функции - PullRequest
0 голосов
/ 28 июня 2018
workObjectMap.computeIfPresent(key, (k,v) -> {
    v.memberIdSet.addAll(memberIdSet);
    v.memberPositionSet.addAll(memberPositionSet);
    return v;
});
// If it.remove() in run() is called at this point,
// there is a risk of the same work being done twice
workObjectMap.putIfAbsent(key, new WorkObjectValue(memberIdSet, memberPositionSet));

У меня есть код выше. В отдельной теме я могу удалить из workObjectMap. Я хочу атомарную функцию, которая изменяет значение, если ключ присутствует, а если его нет, он помещает ключ / значение.

В моем текущем коде есть вероятность, что удаление произойдет между computeIfPresent и putIfAbsent, так что тот же элемент, который уже был добавлен на карту, будет добавлен снова.

Как заблокировать любые удаления между этими двумя вызовами методов? (computeIfPresent и putIfAbsent)

1 Ответ

0 голосов
/ 28 июня 2018

Использование Map.compute():

workObjectMap.compute(key, (k,v) -> {
    if (v == null) return new WorkObjectValue(memberIdSet, memberPositionSet);
    v.memberIdSet.addAll(memberIdSet);
    v.memberPositionSet.addAll(memberPositionSet);
    return v;
});

Обратите внимание, что ConcurrentHashMap Javadoc явно заявляет , что это атомарное.

...