Java 中 long 和 double 的原子性?( 二 )


Implementations of the Java Virtual Machine are encouraged to avoid splitting 64-bit values where possible. Programmers are encouraged to declare shared 64-bit values as volatile or synchronize their programs correctly to avoid possible complications.
从规定中我们可以知道

  1. 对于64位的long和double , 如果没有被volatile修饰 , 那么对其操作可以不是原子的 。在操作的时候 , 可以分成两步 , 每次对32位操作 。
  2. 如果使用volatile修饰long和double , 那么其读写都是原子操作
  3. 对于64位的引用地址的读写 , 都是原子操作
  4. 在实现JVM时 , 可以自由选择是否把读写long和double作为原子操作
  5. 推荐JVM实现为原子操作
从程序得到的结果来看 , 32位的HotSpot没有把long和double的读写实现为原子操作 。在读写的时候 , 分成两次操作 , 每次读写32位 。因为采用了这种策略 , 所以64位的long和double的读与写都不是原子操作 。
在硬件 , 操作系统 , JVM都是64位的情况下呢?对于64bit的环境来说 , 单次操作可以操作64bit的数据 , 即可以以一次性读写long或double的整个64bit 。因此我们可以猜测 , 在64位的环境下 , long和double的读写有可能是原子操作 。在换了64位的JVM之后 , 多次运行 , 结果都是正确的
64-bit运行正确运行正确结果表明 , 在64bit的虚拟机下 , long的处理是原子性的 。




推荐阅读