1.volatile 关键字值保证了内存可见性而不原子性
内存可见性指的是 共享变量 X 在线程A中修改之后,在其他线程中的数据副本全部失效,其他线程需要使用该变量的时候,需要去主内存重新的刷新获取最新的值。volatile 修饰变量之后,可以达到这个要求。
但是 如果针对volatile的一些操作,比如 自增操作。分为了 load 修改 store 三步。汇编指令级别有四步,第四步是加上 一个 内存屏障,避免 指令的重排序规则。
但是在 这三步中,是非线程安全的,在还没有将 store 指令操作完成的时候,如果有其他的线程介入修改 共享变量并更新,此时的值是错误更新的。
在线程 A store 之前 ,B读到 X = 100, 并且store更新 为101,但是A 已经读到了 100(内存可见性已经晚了,是针对执行load操作的时候,需要刷新读取最新的值),store 101。 此时两次自增操作,得到的结果是101,是错误的。(问题在于:如果多个线程对同一个共享变量进行操作,存在资源抢占的问题,结果可能会来回的不断覆盖,每次结果都不同。)
所以可以保证内存可见性,但是无法 原子性。
2.volatile + CAS 算法保证原子性
还是上面的例子:
自增操作:
<