Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 易失性阵列的替代方案_Java_Arrays_Synchronized_Volatile_Java1.4 - Fatal编程技术网

Java 易失性阵列的替代方案

Java 易失性阵列的替代方案,java,arrays,synchronized,volatile,java1.4,Java,Arrays,Synchronized,Volatile,Java1.4,从其他问题中,我了解到volatile数组的元素不是volatile的。只有引用本身是不稳定的 volatile[] int data; Thread A: data[4] = 457; Thread B: System.out.println(data[4]); 在这里,线程B可能永远看不到更新的值 我需要哪些选项/备选方案来实现相同的目标?我希望避免必须同步阵列,因为它几乎从未被更改过。然而,它被一些线程大量读取。同步它很可能会降低吞吐量,这在本例中非常重要 我唯一的选择是写时复制数据结

从其他问题中,我了解到volatile数组的元素不是volatile的。只有引用本身是不稳定的

volatile[] int data;

Thread A: data[4] = 457;
Thread B: System.out.println(data[4]);
在这里,线程B可能永远看不到更新的值

我需要哪些选项/备选方案来实现相同的目标?我希望避免必须同步阵列,因为它几乎从未被更改过。然而,它被一些线程大量读取。同步它很可能会降低吞吐量,这在本例中非常重要

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

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

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

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

在本文中,我了解到重新分配数组引用实现了波动性语义。这将给出正确的结果:

volatile[] int data;

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

这在较旧的JVM上有效吗?

数组被标记为volatile,也就是说,只有引用被标记为volatile。数组本身的元素根本不继承volatile关键字的内存可见性语义

我的建议是在您自己的环境中构建一个
atomicIntergerray
类。您可以保存一个
final int[]数据
referenece并正确同步它

还可以查看
atomicIntergerray

或者你可以使用的

该项目将提供一个并发库,该库在当前使用的所有Java平台上都能以不折衷的性能工作,允许开发完全可移植的并发应用程序。更准确地说,traget范围是Java1.3及以上版本,如果为Java1.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);
类VolatileInt{
易失性int值;
}
VolatileInt[]创建(整数大小){
VolatileInt[]数组=新VolatileInt[大小];

for(int k=0;k使用
arr=arr
管理Java重写数组的存储地址(数组也是Java中的对象)。数组字段
arr[i]
不会获得volatile属性

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

如果你想保持安全,使用<代码>原子*数组东西。是的,额外原子性是昂贵的,但是我想如果你考虑访问时间和存储占用,它比链接结构要好。

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


我同意你的问题,最好的办法是
原子*数组

请阅读我的问题。:)我想避免同步。实际上我读了它,但我找不到任何其他方法来解决它。或者你可以使用后端口api的
原子整数数组
。谢谢。这个“问题”这些后端口API使用的是同步的,我想在这里避免。我需要通过许多线程访问此阵列,并且鉴于阵列几乎从未更新过,我应该尝试消除同步锁。我更新了我的问题。请参见下面的编辑行。你确定需要避免同步吗?你说同步吗ronizing它“很可能会降低吞吐量”-好,但也许您应该编写同步代码并对其进行基准测试,以确定性能是否正常(即,尝试避免过早优化?)我很肯定会的。我的目标是一个旧的JVM,在过去通过用写时拷贝数据结构和易失性访问替换同步来提高性能。我想在这里做同样的事情。这样如何:每个线程可以保存阵列的整个副本,并且可以在数据更改时(不经常)更新每个线程的副本通过在每个线程上使用回调或其他更新函数?(或使用volatile bool标记线程何时应该从主副本更新其值?)这是一个非常有用的注释,聪明的想法。我会考虑这个问题。非常感谢。你也看到我的编辑了吗?这行吗?