关于并发性:在Java中编写long和double不是原子的?

Writing long and double is not atomic in Java?

Reading and writing of a single variable is atomic (language guarantee!), unless the variable is of type long or double.

我在读一门课程的幻灯片,发现它是我写的。这个类是关于并发的。

有人能给我解释一下为什么写长的或双的不是原子操作吗?我真的很吃惊。


它不是原子的,因为它是机器代码级别的多步骤操作。也就是说,long和double比处理器的字长。


只是为了阐明Java、双倍和朗斯的情况,除非它们被声明为EDCOX1,0,否则不被原子化地读取或写入。

JLS-双针和长针非原子治疗


Javalong和double不是32位机器中的原子,而是64位机器中的原子,具有64位JVM中的一些。为什么它依赖于机器的钻头长度?因为32位机器需要两次长时间的写入(只要长64位)。请阅读此了解详细信息。


Java编程语言内存模型,对非易失性长或双值的一次写入被视为两个单独的写入:一个到每个32位的一半。这可能导致线程从一次写入中看到64位值的前32位,从另一次写入中看到第二个32位。


许多程序员必须阅读"3.1.2"中的这一语句。在实践中使用Java并发的非原子64位操作。我参考了最新的JLS 17.7。双龙非原子处理。他们至今仍没有宣称64位JVM是标准的。因此,64位操作被分成32位操作,这些操作会破坏原子性,并且在声明为volatile之前在多线程环境中使用是危险的。在Java中,长和双是64位长的。因此,Java中的书写和读取操作不是原子的。


阅读MaaTiNuS:"Java中的哪些操作被认为是原子的?"当Java中的原始数据类型不是线程安全时,乔恩Skest@读取答案?

根据jls,您可以通过声明它是易失性的,在double和long上进行读写操作,使其成为原子操作。但这并不能确保++是原子的。需要concurrent.atomic包。读一下路易斯·瓦瑟曼的回答。

还有这个博客和评论。