易失性阵列的替代品

时间:2013-04-01 08:12:56

标签: java arrays synchronized volatile java1.4

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

volatile[] int data;

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

此处,线程B可能永远不会看到更新的值。

我有哪些选择/替代方案可以达到同样的目的?我想避免同步数组,因为它几乎不会被改变。但是,有些线程正在阅读它。同步它很可能会降低吞吐量,这在本例中非常重要。

我唯一的选择是写入时复制数据结构吗?也就是说,将数组复制到一个新数组中,然后更新数组引用。

还有其他选择吗?我在某处读到将数组封装成一个类(只有一个成员,数组)实现同样的目的,但我怀疑这是真的。我看不出这可能会有什么帮助。

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

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

Java volatile array?中我读到重新分配数组引用实现了波动性语义。这应该给出正确的结果:

volatile[] int data;

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

这对旧版JVM有效吗?

3 个答案:

答案 0 :(得分:1)

数组标记为volatile,即只将引用标记为volatile。数组本身的元素根本不继承volatile关键字的内存可见性语义。

我可以建议您自己构建一个AtomicIntergerArray课程。您可以在哪里保留final int[] data个推荐并正确同步。

另请查看AtomicIntergerArray implementation code

否则您可以使用Backport apiAtomicIntegerArray

该项目旨在提供一个并发库,该库在当前使用的所有Java平台上都具有无与伦比的性能,允许开发完全可移植的并发应用程序。更确切地说,traget范围是Java 1.3及更高版本,如果为Java 1.2提供,则会提供一些有限的支持。

答案 1 :(得分:1)

只需使用包装器:

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);

答案 2 :(得分:1)

使用arr=arr管理Java来重写数组的存储地址(数组也是Java中的对象)。数组字段arr[i]没有获得volatile属性。

在某些情况下,arr=arr可能会因未知原因而起作用,但它并不会让您安全起见。

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

如果要避免全局锁定,可以考虑将数组拆分为子集。这使得锁只影响子集,并且您仍然保持所有值的波动性。

我分享你的问题,最好的选择是Atomic*Arrays

相关问题