在JVM虚拟机中除(long,double外的基本类型)读取和修改的操作是原子性的,多个线程同时访问时是互斥的,这没有问题。
在JVM虚拟机中Long和double的读取和写入是当做两个分离的32位数据来操作,这样就产生了字撕裂。
如果没有volatile关键字修饰的情况下:
一个long型的变量,线程1读取,这时线程2 恰好修改了其中一个32位,那么线程1读取的就是错误的值了。
有voiatile关键字修饰后,整个变量就会获得可视性,线程间原子操作读取和写入就不会出错了。
如果是自增等操作是不具备原子性的行为,因为自增操作是不具备原子性的,它包括读取变量的原始值、进行加1操作、写入工作内存。那么就是说自增操作的三个子操作可能会分割开执行。自增操作的非原子性会导致,线程将访问的值是对的但是计算的结果是错的,volatile并不能保证线程间的互斥,只能保证读取和写入的原子性。