Java 中的 64 位赋值在 32 位机器上是原子的吗?
2022-09-01 12:28:48
如果我有这样的代码 -
long x;
x = 0xFFFFFFFFL;
如果我在32位机器上运行此代码,它是否保证是原子的,或者是否有可能读取x的不同线程可能获得不完整/垃圾值?
如果我有这样的代码 -
long x;
x = 0xFFFFFFFFL;
如果我在32位机器上运行此代码,它是否保证是原子的,或者是否有可能读取x的不同线程可能获得不完整/垃圾值?
以下是简短的摘要:
int
char
byte
short
boolean
float
double
long
volatile
因此,只有读取/写入可能不是原子的例外情况:
double
long
volatile
因此,就读取/写入共享数据的原子性而言,您只需要进行任何或.其他所有内容都已经保证是原子的,无论在实际实现中使用了多少位。volatile
double
long
以下是此处转载的相关部分,以供快速参考:
JLS 17.7
双长
非原子处理某些实现可能会发现将 64 位或值上的单个写入操作划分为相邻 32 位值上的两个写入操作很方便。为了提高效率,此行为是特定于实现的;Java 虚拟机可以自由地以原子方式或分两部分执行写入和值。
long
double
long
double
出于 Java 编程语言内存模型的目的,对非 or 值的单个写入被视为两个单独的写入:每个 32 位的一半。这可能会导致线程从一次写入中看到 64 位值的前 32 位,从另一次写入中看到第二个 32 位。和 值的写入和读取始终是原子的。对引用的写入和读取始终是原子的,无论它们是作为 32 位值还是 64 位值实现的。
volatile long
double
volatile long
double
鼓励 VM 实现者尽可能避免拆分其 64 位值。鼓励程序员将共享的 64 位值声明为或正确同步其程序,以避免可能出现的复杂性。
volatile
byte
易失性
场int i;
i++
volatile long[]
volatile
long
long
volatile
不,他们不是。64 位存储被视为两个单独的 32 位存储。因此,在并发环境中,该变量可以具有一次写入的高32和另一次写入的低32,这显然不是线程安全的。