java内存模型要求写int
是原子的:也就是说,如果你在一个线程中写一个值(由4个字节组成)并在另一个线程中读取它,你将获得所有字节或无,但从不2个新字节和2个旧字节等。
long
无法保证。在此处,将0x1122334455667788
写入之前持有0
的变量可能会导致另一个帖子显示为0x112233440000000
或0x0000000055667788
。
现在规范并未强制对象引用为int或long。出于类型安全的原因,我怀疑它们是保证以原子方式编写的,但在64位VM上,这些引用可能是非常好的64位值(仅仅是内存地址)。
现在我的问题是:
此致 斯特芬
答案 0 :(得分:54)
请参阅JLS section 17.7: Non-atomic Treatment of double and long
出于Java编程语言内存模型的目的,a 单个写入非易失性long或double值被视为两个 单独写入:每个32位一半。这可能导致a 线程看到64位值的前32位的情况 一次写入,另一次写入的第二次32位。
volatile和long值的写入和读取始终是原子的。
无论如何,写入和读取引用始终是原子的 它们是实现为32位还是64位值。
某些实现可能会发现划分单个写操作很方便 对64位长或双值的操作分为两个写操作 相邻的32位值。为了效率,这种行为是 实现特定的; Java虚拟机的实现 可以自由地对原子或双重值进行写入 两部分。
鼓励Java虚拟机的实现避免 尽可能拆分64位值。鼓励程序员 将共享的64位值声明为volatile或同步其程序 正确地避免可能的并发症。
(强调补充)