【发布时间】:2013-04-01 08:12:56
【问题描述】:
从其他问题中,我了解到 volatile 数组的元素不是 volatile。只有引用本身是可变的。
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 上有效吗?
【问题讨论】:
-
我更新了我的问题。请参阅下面的编辑行。
-
您确定需要避免同步吗?你说同步它“很可能会降低吞吐量” - 好的,但也许你应该编写同步代码并对其进行基准测试以了解性能是否正常(即尽量避免过早优化?)
-
我很确定它会的。我的目标是一个旧的 JVM,并且过去通过用写时复制数据结构和易失性访问替换同步来提高性能。我想在这里做同样的事情。
-
这个怎么样:每个线程是否可以保存数组的完整副本,并且您可以在数据更改时(不经常)通过在每个线程上使用回调或其他更新函数来更新每个线程的副本? (或者使用 volatile bool 来标记线程何时应该从主副本更新其值?)
-
这是一个非常有用的评论,聪明的主意。我会考虑的。非常感谢。你也看到我的编辑了吗?这行得通吗?
标签: java arrays synchronized volatile java1.4