Java volatile数组?
如何使数组变得易变? 因为我已经明白,使数组变得不稳定是不安全的?
声明一个volatile变量不会给它的字段提供volatile访问权限。 你宣称引用本身是不稳定的,而不是它的元素。
换句话说,您声明了一组易变元素,而不是一组易失性元素。 这里的解决方案是使用AtomicIntegerArray以防您想要使用整数。 另一种方式(但有点难看)是每次编辑字段时重写对数组的引用
你做到了
arr = arr;
(正如我所说的……丑陋)
AtomicLongArray,AtomicIntegerArray,AtomicReferenceArray(java.util.concurrent.atomic)。
编辑:java中的数组对象。 如果您对该对象进行volatile的引用,则在交换对该数组的引用时使其对其他线程可见。 但是,这不适用于数组值本身。
为了更好地了解java内存模型,实际上有可能在没有Atomic * Array的情况下绕过它。 使用events-before关系进行易失性读取和正常写入使得它成为可能:
如果线程A在此之后写了一些非易失性的东西和一个volatile变量,那么线程B也可以保证看到易失性内容的变化,但前提是线程B首先读取volatile变量。 另请参阅: 发生在与Java中的volatile字段和synchronized块之间的关系之前 – 以及它们对非易失性变量的影响?
对于数组,这意味着:写入数组后,写入一些易失性状态变量(确保写入实际更改易失性状态变量!)从数组中读取时,首先读取易失性状态变量,然后访问arrays。 易失性读取也应该使所有其他写入也可见,只要它们之前发生过。
OLD:编写自引用arr=arr
实际上并没有帮助。
您编写数组arr
的地址,而不是字段arr[i]
。 所以你仍然没有获得arr[i]
(你想要的)的易失性属性,但仅用于存储地址arr
。
前面提到的Jeremy Manson的博客文章详细解释了它: http : //jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html
他最好的解决方案是使用Atomic * Arrays,即AtomicReferenceArray用于generics类型(基本类型也有特殊forms)。 我无法想象这是特别有效的,特别是因为它获得了你需要的更多属性(primefaces性>> volatile)。
替代方案可以是指针结构,其中容器使用易失性指针字段。 也没那么有效……