Является ли обратный оператор атомарным? - PullRequest
0 голосов
/ 13 ноября 2018

Я вставил некоторый код о параллелизме Java:

public class ValueLatch <T> {

    @GuardedBy("this") private T value = null;
    private final CountDownLatch done = new CountDownLatch(1);

    public boolean isSet() {
        return (done.getCount() == 0);
    }

    public synchronized void setValue(T newValue) {
        if (!isSet()) {
            value = newValue;
            done.countDown();
        }
    }

    public T getValue() throws InterruptedException {
        done.await();
        synchronized (this) {
            return value;
        }
   }

}

Почему return value; необходимо синхронизировать ???

Является ли оператор return не атомарным ??

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

Возврат не нужно синхронизировать. Поскольку CountDownLatch.countDown() не вызывается до тех пор, пока значение не будет установлено в последний раз, CountDownLatch.await() гарантирует, что значение будет стабильным до того, как оно будет прочитано и возвращено.

Разработчик, который написал это, вероятно, не совсем уверен в том, что он делал (параллелизм сложен и опасен) или, что более вероятно, его использование аннотации GuardedBy в value заставило его систему сборки выдать предупреждение на return, и какой-то другой разработчик синхронизировал его без необходимости, просто чтобы убрать предупреждение.

Я говорю «какой-то другой разработчик», потому что этот класс, в противном случае, кажется, специально разработан для того, чтобы getValue() мог работать без блокировки после установки значения.

0 голосов
/ 14 ноября 2018

return value необходимо не необходимо синхронизировать:

  • чтение ссылок является атомарным согласно JLS : "Записывает и читает изссылки всегда атомарные, ... "
  • каждый поток, читающий value, гарантированно увидит свое последнее значение в соответствии с Java Memory Model value = newValue .до done.countDown(), что происходит - до done.await(), что происходит - до return value.По транзитивности value = newValue, таким образом, происходит до return value.
0 голосов
/ 13 ноября 2018

Оператор return должен выполнить операцию чтения над значением .

Операция чтения является атомарной для большинства примитивов, но вы имеете дело с универсальнымЭто означает, что вы не будете знать тип value .

По этой причине возврат должен быть синхронизирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...