原子比较和交换是否可以覆盖惰性写入而不会看到它?

Bee*_*ope 6 java concurrency java-memory-model jls

JLS 的内存模型部分(17.4)以合理的细节描述了volatilevolatile读写的语义,以及与某些其他结构(如监视器进入和退出)的交互.

然而,这并不能完全解释的语义compareAndSwap,也不lazySet在java.util.concurrent.atomic中*类.因为compareAndSet,你有javadoc包中的blurb :

compareAndSet and all other read-and-update operations such as getAndIncrement 
have the memory effects of both reading and writing volatile variables. 
Run Code Online (Sandbox Code Playgroud)

lazySet 提供了一些更难以理解的模糊:

lazySet has the memory effects of writing (assigning) a volatile variable 
except that it permits reorderings with subsequent (but not previous)
memory actions that do not themselves impose reordering constraints with
ordinary non-volatile writes. Among other usage contexts, lazySet may apply 
when nulling out, for the sake of garbage collection, a reference that is 
never accessed again. 
Run Code Online (Sandbox Code Playgroud)

我不清楚的是他们是如何互动的.如果将CAS(compareAndSet)和lazySet发布到相同的原子值,其中CAS expectedValue与lazySet值不同,CAS是否可能会覆盖lazySet值?

更明确地说,给定两个线程T1和T2,AtomicInteger atomic = new AtomicInteger();按如下方式操作:

static CountDownLatch latch = new CountDownLatch(2);

T1 
atomic.lazySet(5);  // L1A
latch.countDown();
latch.await();
int val1 = atomic.get();

T2
atomic.compareAndSet(0, 10);  // L2A
latch.countDown();
latch.await();
int val2 = atomic.get();
Run Code Online (Sandbox Code Playgroud)

这是val1 == val2 == 10一种可能的情况吗?确实,可以val1 val2永远是10?

锁存器不是问题的核心 - 它们只是一种让两个线程一直等到另一个完成的方式,并强制在每个线程的有趣lazySetcompareAndSet操作之间发生,并且稍后读取原子看到国家(没有他们,你当然可以至少看到val2 == 10,暂时).

tza*_*man 2

compareAndSet既是读又是写,因此它确实施加了写顺序约束。根据文档,这意味着lazySet写入将不允许围绕它重新排序。所以不,val1也不val2应该是 10。

编辑:为了澄清,本质上所做的是,它对于也写入lazySet相同内容的任何其他原子操作的目的执行原子写入,但对于仅读取的其他原子操作来说是非原子的

更多潜在有用的讨论在AtomicInteger lazySet vs. set,最有用的花絮是添加惰性方法的原始变更集的链接:http://bugs.java.com/bugdatabase/view_bug.do ?bug_id=6275329