返回语句是原子的吗?

时间:2018-11-13 15:51:57

标签: java concurrency

我粘贴了一些有关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 :(得分:8)

返回不需要同步。由于CountDownLatch.countDown()直到最后一次设置该值之后才被调用,因此CountDownLatch.await()确保在读取和返回该值之前是稳定的。

写这篇文章的开发人员可能不太确定自己在做什么(并发既困难又危险),或者更有可能的是,他在GuardedBy上使用value注释导致了他的构建系统在return上发出警告,而其他一些开发人员则不必要地同步它,只是为了消除警告。

我说的是“其他开发者”,因为否则该类似乎是专门为允许getValue()进行设置而无需锁定而继续进行的。

答案 1 :(得分:2)

return语句需要对 value 进行读取操作。

大多数 原语的读取操作是原子的,但是您要处理的是泛型,这意味着您将不知道 value 的类型。

因此,退货应保持同步。

答案 2 :(得分:2)

return value不需要 进行同步:

  • 根据JLS,引用的读取是原子的:“引用的写入和读取始终是原子的,...”
  • 保证每个线程读取value都可以按照Java Memory Model value = newValue happens-before done.countDown()的方式查看其最新值。 先于 done.await()先于 return value。通过传递性value = newValue,因此先于 return value