【发布时间】:2015-04-24 11:28:48
【问题描述】:
Java 通过其原子类公开 CAS 操作,例如
boolean compareAndSet(expected,update)
JavaDocs 指定 compareAndSet 操作的记忆效果如下:
compareAndSet 和所有其他读取和更新操作 如 getAndIncrement 具有两者的记忆效应 读取和写入 volatile 变量。
这绝对适用于成功的compareAndSet 调用。但是如果 compareAndSet 返回false,记忆效应是否也成立?
我会说不成功的compareAndSet 对应于易失性读取(因为在这种情况下必须访问原子实例的当前值),但我不明白为什么 CAS 应该执行特殊的内存屏障指令失败的案例。
问题实际上是,不成功的 CAS 是否也建立了先发生关系。考虑以下程序:
public class Atomics {
private static AtomicInteger ai = new AtomicInteger(5);
private static int x = 0;
public static void main(String[] args) {
new Thread(() -> {
while (x == 0) {
ai.compareAndSet(0, 0); // returns false
}
}, "T1").start();
new Thread(() -> {
x = 1;
ai.compareAndSet(0, 0); // returns false
}, "T2").start();
}
}
线程 T2(和程序)一定会终止吗?
【问题讨论】:
-
他们为什么不呢?
-
好吧,如果规范没有要求,那么 VM 可以省略执行其他必要的屏障指令。
-
@Dominik 我不认为你的程序一定会终止。
标签: java concurrency java-memory-model compare-and-swap