是否在32位机器上使用Javaprimefaces进行64位分配?

如果我有这样的代码 –

long x; x = 0xFFFFFFFFL; 

如果我在32位机器上运行此代码,它是否保证是primefaces的,或者可能是读取x的不同线程可能得到不完整/垃圾值?

以下是简短摘要:

  • 对于引用,读/写总是primefaces的(即使在64位实现中!)
  • 对于intcharbyteshortbooleanfloat ,读/写总是primefaces的
  • 对于doublelong ,如果它们是volatile ,则读/写总是primefaces的

因此,只有读/写可能不是primefaces的exception:

  • 对于doublelong ,如果它们没有声明为volatile则不保证它们是primefaces的

因此,就读/写共享数据的primefaces性而言,您只需要将volatile doublelong 。 无论在实际实现中使用了多少位,其他所有内容都已保证是primefaces的。


在规范上

以下是此处转载的相关部分,以供快速参考:

JLS 17.7 doubleprimefaces和非primefaces的非primefaces化处理

一些实现可能发现将64位longdouble值上的单个写操作划分为相邻32位值上的两个写操作是方便的。 为了效率,这种行为是特定于实现的; Java虚拟机可以primefaces地或分两部分自由地写入longdouble值。

出于Java编程语言存储器模型的目的,对非易失volatile longdouble值的单个写入被视为两个单独的写入:每个32位半写一个。 这可能导致线程从一次写入看到64位值的前32位,而从另一次写入看到第二次32位的情况。 volatile longvolatile 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的。