Java普通变量(未用volatile的修饰)的读和写是否是原子性的?

再读《java并发编程艺术》这本书的时候学到了volatile,作者在书中强调了,volatile可以保证读和写具有原子性。让我心生疑惑难道普通的变量读和写就不具有原子性了吗?我记得好多人都曾说过java普通变量的赋值和读取操作是原子性的。然后这一堆概念在我脑子里变成了浆糊,它们似乎冲突着矛盾着,但又各自有各自的道理。我对原子性真的感到十分疑惑。
我试着这样分析一下:读取一个变量需要两部操作从主内存read出来,然后再load到工作内存,如果这两个指令中间重排序了其他的指令,那这样看来,读取一个变量真的不是原子操作。给一个变量赋值,也是有多个指令组成,如果中间加入了其他的操作那也谈不上原子性了。这样分析的话普通变量赋值和读取严格意义上谈不上原子操作,但是这样分析感觉别人说的赋值和读取是不可分割的又十分的冲突。到底什么才是原子操作,就好比一个线程修改了一个普通变量,但是它没有及时写会主内存,它还是原子操作吗?
翻阅古今
浏览 368回答 2
2回答

至尊宝的传说

可以参考这里:TheJava®LanguageSpecificationJavaSE8EditionForthepurposesoftheJavaprogramminglanguagememorymodel,asinglewritetoanon-volatilelongordoublevalueistreatedastwoseparatewrites:onetoeach32-bithalf.Thiscanresultinasituationwhereathreadseesthefirst32bitsofa64-bitvaluefromonewrite,andthesecond32bitsfromanotherwrite.Writesandreadsofvolatilelonganddoublevaluesarealwaysatomic.Writestoandreadsofreferencesarealwaysatomic,regardlessofwhethertheyareimplementedas32-bitor64-bitvalues.Someimplementationsmayfinditconvenienttodivideasinglewriteactionona64-bitlongordoublevalueintotwowriteactionsonadjacent32-bitvalues.Forefficiency'ssake,thisbehaviorisimplementation-specific;animplementationoftheJavaVirtualMachineisfreetoperformwritestolonganddoublevaluesatomicallyorintwoparts.ImplementationsoftheJavaVirtualMachineareencouragedtoavoidsplitting64-bitvalueswherepossible.Programmersareencouragedtodeclareshared64-bitvaluesasvolatileorsynchronizetheirprogramscorrectlytoavoidpossiblecomplications.在虚拟机规范中并没有规定对非volatile的double和long的读写是原子的,但是虚拟机的具体实现也可以是原子的,对于volatile修饰的,读写必须为原子的。经测试,在32位的intel机器上,不是原子的,在64位的intel机器上是原子的

慕妹3146593

volatile关键字解决的不是原子性问题,而可见性问题.多核多CPU环境下,每个线程可能因CPU高速缓存各自分离的原因,一个线程看不到另一个线程修改的结果,因为缓存还没有刷新到主内存的原因.volatile关键字确保每次在做修改时都直接写入主内存(或同步高速缓存).从而保障各个线程都能看到修改结果.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript