Can atomic comparison and exchange overwrite a lazy record without seeing it?

The JLS memory model section (17.4) describes, within reasonable limits, the semantics of volatile and non- volatile for reading and writing, as well as interaction with some other constructs, such as the input and output of the monitor.

However, it does not fully explain the semantics of compareAndSwap and lazySet for the java.util.concurrent.Atomic * classes. For compareAndSet , you have an ad unit from the javadoc package:

 compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables. 

lazySet offers a slightly more incomprehensible ad unit:

 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. 

It’s not clear to me how they interact. If you issue CAS ( compareAndSet ) and lazySet for the same atomic value, where the expected CAS validity is different from the lazySet value, is it possible that CAS is overwriting the lazySet value?

More explicitly, given the two threads, T1 and T2, running on a common AtomicInteger atomic = new AtomicInteger(); in the following way:

 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(); 

Is val1 == val2 == 10 possible scenario here? Indeed, can val1 or val2 be 10?

Latches are not the basis for the question - this is just a way for both threads to wait until the other is executed, and forcing this to happen earlier between the interesting lazySet and compareAndSet for each thread, and later readings of the atom to see the state (without them you could, of course, see at least val2 == 10 , temporarily).

+6
source share
1 answer

compareAndSet is both read and write, so it imposes a restriction on the write order. In documents, this means that lazySet write will not be allowed to reorder around it. So no, val1 and val2 should never be 10.

EDIT: To clarify what lazySet does, essentially, it does atomic writing for the purposes of any other atomic operation, which also writes the same thing, but non-atomic for other atomic operations that it just reads.

A more potentially useful discussion in AtomicInteger lazySet versus the installed one , the most useful tidbit is the link to the original changeset where the lazy methods were added: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6275329

+2
source

Source: https://habr.com/ru/post/981593/


All Articles