volatile为什么不能保证变量原子性

    技术2022-07-11  107

    看个例子,仅是个人理解。 

    public class VolatileDemo { public static volatile int count; public static void main(String[] args) { count++; } }

    当进行自增操作,字节码是这样的

     

    1、获取变量的值并入栈

    2、把1入栈

    3、依次取出栈中两个操作数相加并入栈(假设为临时变量t)

    4、取出栈顶值赋值给变量

    而volatile的可见性指的是第4步,当修改变量后,把新值刷新到内存,并使其他线程使用此变量的的缓存行失效(多核处理器),那么会重新读取变量的值,即缓存一致性;但是如果其他线程已经已经进行到了第3步,那么意味着仅仅是重新读了一遍新的变量值,会直接将已经计算好的t赋值给变量。

    public class VolatileDemo { public static volatile int count; public static int a = 1; public static void main(String[] args) { count = a; } }

    而当自增操作变成这样的,字节码是这样的

    1、获取a的值并压入栈

    2、取出栈顶元素赋值给count

    这样的话即使第一步被其他线程打断,并且a的值被修改,那也是重新获取一遍,并赋给count,不会存在安全问题。

    所以看来volatile不会保证(i++)这样复合操作的原子性。

    Processed: 0.009, SQL: 9