CompareAndSet memory effect of failed operations

Java provides a CAS operation through its atomic classes, for example.

boolean compareAndSet(expected,update)

JavaDocs defines the memory effects of the compareAndSet operation as follows:

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

This is true for successful calls compareAndSet. But memory effects are also saved if compareAndSet returns false?

I would say that the failure compareAndSetcorresponds to volatile reading (since in this case it is necessary to access the current value of the atomic instance), but I do not understand why CAS should follow special instructions to protect memory in the unfortunate case.

The question really is whether the failed CAS establishes a connection between events. Consider the following program:

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

Will the T2 thread (and the program) definitely stop?

+4
source share
2 answers

volatile , . T1 volatile, T2 , , T2 , T1 . , , T1 T2, , .

- , T2. , T1 , "". volatile boolean fooIsInitialized volatile int currentPhase. , , .

, . , T2 cas T1 , cas . . , T1 T2, . , T1 , 100% , T2, .

T2, , JVM, T1, T1, - T2. - , - , . , , T1, T2 (.. ), , , cas .

+1

, - , , . , ? , .

    new Thread(() -> {
        if(x == 0){
            while (true) {
                ai.compareAndSet(0, 0); // returns false
            }
        }
    }, "T1").start();

? . , , , . , .

: , , . , , .

0

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


All Articles