基本类型为什么是原子性的?和内存有关系还是什么?哪位大佬解释下原理?
百度看了下没有一个答案解释原理,都是照猫画虎,也不知道是真懂还是假懂
因为Java被设计成支持多线程的语言,如果基本类型的读取不是原子性的,那么代码无论怎么写,都不能做到多线程并发安全(即对变量的读、修改、写回在并发过程中保持正确)。
首先了解一下原子性的概念,原子性是一个操作不能被打断,要么全部执行完毕,要么不执行。
而基本数据类型的原子性是特指在除了long、double外的基本数据类型的赋值及读取操作为原子性的(注意不包括自加自减等运算操作)
在单线程的情况下,比如int a = 1; 那么这个赋值操作就是原子性的,但是这个原子性只是相对的,在多线程的状态下可能会导致后一个线程读取到前一个线程修改前的值并修改,所以可以采取加volatile关键字保证可见性,或者使用原子操作类atomic的方式。
具体的你看下面这篇文章吧 https://www.jianshu.com/p/7f0ffb102085
事实上long和double赋值是不是原子性的,要看操作系统,如果操作系统是32位的话,就不能完全保证原子性,因为对于32位虚拟机来说,每次原子读写是32位的,而long和double则是64位的存储单元,这样会导致一个线程在写时,操作完前32位的原子操作后,轮到B线程读取时,恰好只读取到了后32位的数据,这样可能会读取到一个既非原值又不是线程修改值的变量,它可能是“半个变量”的数值,即64位数据被两个线程分成了两次读取。但是目前商业虚拟机都把64位的数据读写操作作为原子操作来执行,这是个人看法,不代表权威
基本类型的原子性,是依靠Java内存模型定义的6个原子性变量操作(read、load、assign、use、store、write)以及缓存一致性来保证的
Java内存模型定义的6个原子性变量操作保证了变量在执行引擎、高速缓存、主内存之间操作的原子性;而缓存一致性保证了某个执行引擎在改变其高速缓存中的变量后,其他线程不能对该变量做修改,即当其他处理器回写已被锁定的缓存行的数据时会起缓存行无效