比如有两个线程,Thread1和Thread2。

1、每个线程都有自己的工作内存,将主内存中的数据缓存到自己工作内存中。此时,Thread1和Thread2都通过read+load将data=0缓存到自己的工作内存中。

2、cpu切换到Thread1时,Thread1会将data=0 use进cpu里面计算data++的操作,但是没来得及将data++的结果data=1,assign回Thread1的工作内存中。cpu此时切换到Thread2,然后在Thread2线程也做了同样的操作(data=0 use进cpu并执行data++),继续assign回Thread2的工作内存,并store+write将data=1写回主内存。

3、因为data是用volatile修饰的,根据缓存一致性协议,其他的线程就会立即知道自己工作内存中的值已经失效,然而,并没有。因为Thread1之前已经将data=0 use进cpu进行计算了,cpu切换回Thread1时,Thread1将之前计算好的data=1 assign到自己的工作内存中,并store+write写回主存。通过以上的执行顺序,两个线程分别对data做了一次data++操作,得到的data=1而不是我们预期中的data=2。

4、多线程同时修改一个被volatile修饰的共享变量时,不能保证原子性,只能保证可见性和顺序性。