是否在32位机器上使用Javaprimefaces进行64位分配?
如果我有这样的代码 –
long x; x = 0xFFFFFFFFL;
如果我在32位机器上运行此代码,它是否保证是primefaces的,或者可能是读取x的不同线程可能得到不完整/垃圾值?
以下是简短摘要:
- 对于引用,读/写总是primefaces的(即使在64位实现中!)
- 对于
int
,char
,byte
,short
,boolean
,float
,读/写总是primefaces的 - 对于
double
和long
,如果它们是volatile
,则读/写总是primefaces的
因此,只有读/写可能不是primefaces的exception:
- 对于
double
和long
,如果它们没有声明为volatile
, 则不保证它们是primefaces的
因此,就读/写共享数据的primefaces性而言,您只需要将volatile
double
或long
。 无论在实际实现中使用了多少位,其他所有内容都已保证是primefaces的。
在规范上
以下是此处转载的相关部分,以供快速参考:
JLS 17.7
double
primefaces和非primefaces的非primefaces化处理一些实现可能发现将64位
long
或double
值上的单个写操作划分为相邻32位值上的两个写操作是方便的。 为了效率,这种行为是特定于实现的; Java虚拟机可以primefaces地或分两部分自由地写入long
和double
值。出于Java编程语言存储器模型的目的,对非易失
volatile long
或double
值的单个写入被视为两个单独的写入:每个32位半写一个。 这可能导致线程从一次写入看到64位值的前32位,而从另一次写入看到第二次32位的情况。volatile long
和volatile long
值的写入和读取始终是primefaces的。 对引用的写入和读取始终是primefaces的,无论它们是实现为32位还是64位值。建议VM实现者尽可能避免拆分64位值。 建议程序员将共享的64位值声明为
volatile
或正确同步其程序以避免可能的复杂情况。
也可以看看
- JLS 17.6字撕裂 – 保证例如可以在没有邻居干扰的情况下更新
byte
- JLS 8.3.1.4
volatile
字段 - Java教程/基本类/并发/primefaces变量
- 注意给定
int i;
,i++
不是primefaces的!
- 注意给定
相关问题
- 使用挥发性长的是否有任何意义?
- 如何用Java声明数组元素volatile?
-
volatile long[]
是对long
数组的volatile
引用 -
long
元素本身并不volatile
-
不,他们不是。 64位存储被视为两个独立的32位存储。 因此,在并发环境中,变量可以具有一个写入的高32和另一个写入的低32,显然不是线程安全的。
Java虚拟机规范的第8.4节规定,未声明为volatile的double或long被视为两个32位变量,用于加载,存储,读取和写入操作。
此外,没有定义编码方式和两个32位操作的顺序。
该规范确实鼓励实现使操作成为primefaces,但它们不需要它。
如果变量是volatile
,则读/写保证是primefaces的,但如果变量是非易失性的则不是。
一些实现可能发现将64位长或双值上的单个写操作划分为相邻32位值上的两个写操作是方便的。 为了效率,这种行为是特定于实现的; Java虚拟机可以primefaces地或分两部分自由地写入long和double值。
出于Java编程语言存储器模型的目的,对非易失性long或double值的单次写入被视为两个单独的写入:每个32位一半写入一次。 这可能导致线程从一次写入看到64位值的前32位,而从另一次写入看到第二次32位的情况。 volatile和long值的写入和读取始终是primefaces的。
JLS 17.7 – 双primefaces和非primefaces的非primefaces化处理
当多个线程在没有同步的情况下访问long值时,必须使用volatile
来确保一个线程所做的更改对其他线程可见,并确保读/写是primefaces的。