简体   繁体   English

compareAndSwap 一个普通成员(非易失性成员)仍然具有易失性读写的内存语义

[英]compareAndSwap a common member ( non-volatile member ) still has memory semantics of volatile read and write

When i read AbstractQueuedSynchronizer in jdk1.8, i see the comment that compareAndSetState method has memory semantics of a volatile read and write .当我在 jdk1.8 中阅读AbstractQueuedSynchronizer时,我看到compareAndSetState方法具有易失性读写的内存语义的评论。

The comment and code are as follows:注释和代码如下:

/**
 * Atomically sets synchronization state to the given updated
 * value if the current state value equals the expected value.
 * This operation has memory semantics of a {@code volatile} read
 * and write.
 */
protected final boolean compareAndSetState(int expect, int update) {
    return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

In AbstractQueuedSynchronizer class, the stateOffset is a volatile member called state在 AbstractQueuedSynchronizer 类中, stateOffset是一个名为state的 volatile 成员

Just wonder what memory semantics is if state is a non-volatile member ..只是想知道如果state是非易失性成员,内存语义是什么......

The semantics for compareAndSetState() are still that of a volatile read and write - this is the main reason why Unsafe.compareAndSwapInt() exists. compareAndSetState()的语义仍然是 volatile 读写的语义——这是Unsafe.compareAndSwapInt()存在的主要原因。

But usually the code doesn't only call Unsafe.compareAndSwapInt() .但通常代码不仅仅调用Unsafe.compareAndSwapInt() Usually the code reads the current value, calculates a new value and then tries to replace the value it has read with the new value.通常代码读取当前值,计算一个新值,然后尝试用新值替换它读取的值。 And this read also must be done using volatile read semantics.而且这种读取必须使用易失性读取语义来完成。

For example, in CountDownLatch.Sync#tryReleaseShared() :例如,在CountDownLatch.Sync#tryReleaseShared()中:

 protected boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; } }

Reading the state with getState() must use volatile read semantics to make sure it uses the latest value.使用getState()读取state必须使用 volatile 读取语义,以确保它使用最新值。

And yes, in principle you could refuse to declare a field like state as volatile.是的,原则上你可以拒绝将state这样的字段声明为 volatile。 But then you must make sure that every access to that field goes through compareAndSwapInt() , getIntVolatile() and putIntVolatile() .但是你必须确保对该字段的每次访问都通过compareAndSwapInt()getIntVolatile()putIntVolatile() If some maintainer of the code forgets this rules and adds a single direct read of the field your code will break in unexpected ways at the most disadvantageous moment in time - for example while giving a presentation to an important customer.如果代码的某些维护者忘记了此规则并添加了对该字段的单次直接读取,您的代码将在最不利的时刻以意想不到的方式中断 - 例如,在向重要客户进行演示时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM