我正在尝试将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的任何线程都将看到它).
原文地址:https://codeday.me/bug/20190706/1393640.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。