По сути, это продолжение этого или это или многие другие в этом отношении.
Мой вопрос, вероятно, прост: если я использую ConcurrentHashMap::compute
только, как для чтения, так и для записи, достаточно ли этого для обеспечения видимости?
Я знаю этот compute
метод:
Весь вызов метода выполняется атомарно
Достаточно ли этого, чтобы гарантировать видимость? В частности, является ли эта истинная спецификация/документация мудрой в отношении happens-before
? Чтобы упростить мой вопрос, вот пример:
static class State {
private int age;
int getAge() {
return age;
}
State setAge(int age) {
this.age = age;
return this;
}
}
а также :
// very simplified, no checks
static class Holder {
private static final ConcurrentHashMap<String, State> CHM = new ConcurrentHashMap<>();
public State read(String key) {
return CHM.compute(key, (x, y) -> y);
}
public State write(String key, int age) {
return CHM.compute(key, (x, y) -> y.setAge(y.getAge() + age));
}
}
Никто не имеет доступа к CHM
и может работать только через Holder
.
Для меня ответ, очевидно, да, это безопасно, и все читатели увидят результат последнего метода write
. Я просто не могу соединить точки с документацией ConcurrentHashMap
, что, скорее всего, очевидно, но я, кажется, упустил это.
read
? Он увидит «результат последней операцииwrite
», но какая запись была последней? Без какого-либо определенного порядка ничего еще может не произойти, и все они могут выполняться прямо сейчас, одновременно с вызывающей стороной методаread
. - person Holger   schedule 04.06.2021read()
вы можете использоватьCHM.get()
и жить долго и счастливо. - person Tamas Rev   schedule 04.06.2021get
. Комментарии и первоначальные вопросы, на которые я ссылался, обсуждают это гораздо шире. - person Eugene   schedule 04.06.2021