Java volatile数组?

Mic*_*ael 16 java volatile

如何使数组易变?因为我已经明白了,使数组变得不稳定是不安全的吗?

nic*_*aas 17

声明一个volatile变量不会给它的字段提供volatile访问.你声明引用本身是volatile,而不是它的元素.

换句话说,你要声明一个挥发性组的元素,而不是一个集易挥发元素.这里的解决方案是用于AtomicIntegerArray你想要使用整数的情况.

另一种方式(但有点难看)是每次编辑字段时重写对数组的引用.

你这样做:

arr = arr; 
Run Code Online (Sandbox Code Playgroud)

(正如我所说的......丑陋)

  • 我真的不认为这是解决问题的办法。问题在于(据我所知,部分是)缓存一致性,以及字节码系统和 JVM 本身的定义中几乎完全缺乏强大的内存排序语义。重写数组引用并不能保证您能够连贯地刷新写入缓存或内存的任何数组元素,以便所有线程都具有相同的元素视图。 (3认同)
  • 我不认为易失性的元素与元素的访问是原子的相同. (2认同)

jta*_*orn 7

AtomicLongArray,AtomicIntegerArray,AtomicReferenceArray(java.util.concurrent.atomic).


mar*_*kus 5

编辑:数组中的Java对象。如果使对该对象的引用可变,则在交换对该数组的引用时,使其对其他线程可见。但是,这不适用于数组值本身。

为了更好地了解Java内存模型,实际上有可能在没有Atomic * Array的情况下解决它。使用volatile读取和普通写入的before-before关系可以实现:

如果线程A写入一些非易失性的东西和挥发性变量之后的是,线程B保证看到的挥发性东西的变化,以及,但仅当线程B首先读出挥发性变量。另请参见: 与Java中的易失字段和同步块发生关系-及其对非易失性变量的影响?

对于阵列,这意味着:写入阵列后,写入一些易失性状态变量(确保写入实际上更改了易失性状态变量!)从阵列中读取时,请先读取易失性状态变量,然后访问数组。易失性读取应该使所有其他写入也可见,只要它们之前发生过即可。

老:写自我参考arr=arr并没有实际帮助。

您写入数组的地址arr,而不是字段的值arr[i]。因此,您仍然不会arr[i](想要)获得任何易失性属性,而仅获得存储地址arr

前面提到的杰里米·曼森(Jeremy Manson)的博客文章对此进行了详细说明:http : //jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html

他的最佳解决方案是使用Atomic * Arrays,即用于泛型类型的AtomicReferenceArray(也存在用于基本类型的特殊形式)。我无法想象这是特别有效的,特别是因为它可以为您提供更多所需的属性(原子性>>挥发性)。

另一种可能是指针结构,其中容器使用易失性指针字段。也没有那么高效...