-->

挥发性阵列的替代品(alternatives for volatile array)

2019-08-18 13:11发布

从其他的问题,我了解到,挥发性数组的元素不挥发。 只有引用本身是挥发性的。

volatile[] int data;

Thread A: data[4] = 457;
Thread B: System.out.println(data[4]);

在这里,线程B可能永远不会看到更新后的值。

其中选择/替代我必须做到同样的事情? 我想,以避免对阵列进行同步,因为它几乎没有改变。 但是,它是由一些线程读了很多。 同步将很可能降低了吞吐量,这是在这个例子中很重要的。

是我唯一的选择一个写入时复制的数据结构在这里? 也就是说,复制阵列到一个新的数组,并随后更新数组参考。

是否还有其他选择吗? 我读的地方,该阵列封装到一个类(只有一个成员,即阵列)达到同样的事情,但我怀疑这是真的。 我看不出如何可能的帮助。

请注意,我的目标是JVM 1.4。 这意味着我不能使用java.util.concurrent包。

--------------编辑编辑编辑--------------

在Java中的volatile阵列? 我读重新分配阵列基准实现波动语义。 这应该给正确的结果:

volatile[] int data;

Thread A: data[4] = 457;
Thread A: data = data;
Thread B: System.out.println(data[4]);

这是在旧的JVM是否有效?

Answer 1:

阵列被标记挥发性的,这仅仅是参考被标记为挥发性的。 数组元素本身不继承volatile关键字的存储可见性语义的。

我会建议建立一个AtomicIntergerArray在自己的类。 在这里你可以保持一个final int[] data refernece并正确进行同步。

还采取一看AtomicIntergerArray 实现代码 。

否则,你可以使用反向移植APIAtomicIntegerArray

该项目是提供并发库,对所有Java平台,同时不牺牲性能的作品目前正在使用,允许完全可移植的并发应用程序的开发。 更确切地说,追求的目标范围是1.3的Java及以上,和一些有限的支持,如果提供的用于Java 1.2。



Answer 2:

只需使用包装:

class VolatileInt{
    volatile int value;
}

VolatileInt[] create(int size){
    VolatileInt[] array = new VolatileInt[size];
    for(int k=0;k<size;k++)
        array[k]=new VolatileInt();
    return array; 
}

VolatileInt[] array = create(10);


Answer 3:

使用arr=arr管理着的Java重写阵列的存储地址(阵列也是对象在Java中)。 阵列字段arr[i]不获得挥发性属性。

在某些情况下, arr=arr可能会奏效,原因不明,但它不会给你带来安全可靠。

如果你想保持安全,使用Atomic*Array的东西。 是的,额外的原子是昂贵的,但我想如果你考虑访问时间和存储空间,它比联结构的更好。

如果你想避免全球锁,你可以考虑到阵列分成子集。 这使得锁只影响一个子集,你仍然保留所有值的波动。

我同意你的问题,通过最好的办法是Atomic*Arrays



文章来源: alternatives for volatile array