微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 如何实现volatile元素的数组

我正在尝试将Java应用程序移植到Scala. Java应用程序的一部分有一个名为AtomicDoubleBuffer的实现,它使用AtomicLongArray引擎 – 使用Double.longBitsToDouble(value)的结果从双缓冲区读取,Double.doubleToRawLongBits(value)读取到缓冲区.

我一直在寻找可以更好的Scala实现的网络,我在this登陆,它说这个代码

class VolatileDoubleArray(val length : Int){
  val array = new Array[Double](length);
  @volatile var marker = 0;
  def apply(i : Int) = {marker; array(i); }
  def update(i : Int, x : Double) { array(i) = x; marker = 0; }
}

应该给我发生 – 保证之前.但我对这种可能性有点困惑.为什么一个变量上的volatile标记确定先前的非易失性“操作”成功?我对JSL 17.4.5的解释表明,在一个线程中更新数组元素并不能保证其他线程会看到该更新.我错过了什么吗?或者我是否混淆了整个发生过的事情?

解决方法:

您的示例中的此实现是正确的,并且在保证之前发生.

因为写入volatile变量使得写入线程之前所做的所有事情都对第一次读取这个volatile变量的线程可见.

在这种情况下,易失性“标记”变量是记忆障碍的关键.

在您的示例代码中:

class VolatileDoubleArray(val length : Int){
  val array = new Array[Double](length);
  @volatile var marker = 0;
  def apply(i : Int) = {marker; array(i); }
  def update(i : Int, x : Double) { array(i) = x; marker = 0; }
}

当您在更新中写入数组时,您还使用marker = 0;之后立即写入volatile变量,
在从数组中应用任何读取之前,您首先只通过语句标记读取volatile变量;

这使得对数组的任何写入(甚至由不同的线程执行)对任何读取都是可见的(在保证之前发生,在这种情况下,在任何更新完成之后,执行apply的任何线程都将看到它).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐