volatile can guarantee atomicity it?

volatile can not guarantee atomicity.
When the self-operating together with the increase, the operation itself is not atomic increment operation.

class Data {
    public volatile int number;
    public void add(){
        number++;
    }
}
public class Main {
    public static void main(String[] args) {
        Data data = new Data();
        for (int i=0; i<10; i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i=0; i<2000; i++) {
                        data.add();
                    }
                }
            }, String.valueOf(i)).start();
        }
        while (Thread.activeCount() >=2) {
            Thread.yield();
        }
        System.out.println(data.number);
    }
}

output number is not 20,000.
There is there is a misunderstanding of, volatile keyword ensures visibility is not wrong, but wrong in the above procedure can not guarantee atomicity. Visibility can only guarantee that every reading is current value, but no way to guarantee the volatile atomic operations on variables.
  In the already mentioned, we do not have self-energizing operation is atomic, comprising variables read original value, are incremented, memory write operation . Then that increment operator of three sub-operations may be divided executed, it may lead to the following situation occurs:

If a variable time inc is 10,

Thread 1 of variables increment operation, the thread 1 first reads the value of the original variable inc, then thread 1 is blocked;

Then thread 2 for variables increment operator, thread 2 also to read the original value of the variable inc, due to the variable inc thread 1 just read operation, but did not modify the operation of variables, so it will not cause the worker thread 2 void inc variable cache memory a cache line, the thread will go directly to the main memory 2 to read the value of inc, inc found value 10, and then are incremented, and the write working memory 11, and finally into the main memory .

Thread 1 then subsequently are incremented, since the value has been read inc, note that this case is in the working memory 11 in the thread 1 is the value of inc is still 10, so after one pair of thread are incremented inc inc and and then write working memory 11, and finally into the main memory.

Then two threads were carried out once since the increment operator, inc increased by only 1. Written back to main memory overwrite problems.

Explain here, may have a friend be in doubt, do not, ah, not a guarantee in front of a variable in a volatile variable is modified, it will cache line is invalid? Then another thread to read will read the new value of this right. This is a volatile variable rules above happens-before rules, but note that the variable thread 1 after a read operation, was blocked, it does not modify the value inc. Although volatile and can guarantee the value of the variable reading thread 2 inc is read from memory, but does not modify the thread 1, the thread 2 would not see the value changes.

Rooted here, increment operation is not atomic operations, but can not guarantee that any volatile operating variables are atomic.

Reprinted address: https: //my.oschina.net/134596/blog/3039654

Published 59 original articles · won praise 15 · views 558

Guess you like

Origin blog.csdn.net/qq_45287265/article/details/105054775