再读《java并发编程艺术》这本书的时候学到了volatile,作者在书中强调了,volatile可以保证读和写具有原子性。让我心生疑惑难道普通的变量读和写就不具有原子性了吗?我记得好多人都曾说过java普通变量的赋值和读取操作是原子性的。
然后这一堆概念在我脑子里变成了浆糊,它们似乎冲突着矛盾着,但又各自有各自的道理。
我对原子性真的感到十分疑惑。
我试着这样分析一下:
读取一个变量需要两部操作从主内存read出来,然后再load到工作内存,如果这两个指令中间重排序了其他的指令,那这样看来,读取一个变量真的不是原子操作。
给一个变量赋值,也是有多个指令组成,如果中间加入了其他的操作那也谈不上原子性了。
这样分析的话普通变量赋值和读取严格意义上谈不上原子操作,但是这样分析感觉别人说的赋值和读取是不可分割的又十分的冲突。
到底什么才是原子操作,就好比一个线程修改了一个普通变量,但是它没有及时写会主内存,它还是原子操作吗?
可以参考这里:The Java® Language Specification Java SE 8 Edition
在虚拟机规范中并没有规定对非 volatile 的 double 和 long 的读写是原子的,但是虚拟机的具体实现也可以是原子的,对于 volatile 修饰的,读写必须为原子的。
经测试,在 32 位的 intel 机器上,不是原子的,在 64 位的 intel 机器上是原子的