gpt4 book ai didi

scala - @volatile 用法不清楚 - 将带有 `var` 的对象发送到另一个线程

转载 作者:行者123 更新时间:2023-12-01 19:09:09 25 4
gpt4 key购买 nike

我不确定我在这里是否正确使用了@volatile。我有一个缓冲区,如下所示:

final class BufD(val buf: Array[Double], @volatile var size: Int)

它是在进程之间发送的,因此它可能会跨越线程边界。发送者可以在发送之前更新size字段。因此,我想确保接收者在任何情况下都不能在此处看到过时的 size 值。 第一个问题:@volatile能确保这一点还是多余的?

现在我介绍一个特点:

trait BufLike {
@volatile var size: Int
}

final class BufD(val buf: Array[Double], @volatile var size: Int) extends BufLike

这给了我一个编译器警告:

Warning:(6, 4) no valid targets for annotation on method size - it is discarded unused. You may specify targets with meta-annotations, e.g. @(volatile @getter)

 @volatile var size: Int
^

第二个问题:我应该删除这里的@volatile还是以不同的方式更改它?

最佳答案

我假设线程 A 创建、更新对象 X,然后将对象 X 传递给线程 B。如果对象 X 以及它直接或传递地引用的任何内容(字段)没有被线程 A 进一步更新,则 volatile 是多余的。接收线程中 object-X 状态的一致性由 JVM 保证。

换句话说,如果对象 X 的逻辑所有权从线程 A 传递到线程 B,那么 volatile 就没有意义。相反,在现代多核系统上, volatile 对性能的影响可能比不可变案例类留下的线程本地垃圾更大。

如果对象 X 应该被共享用于写入,那么使字段 volatile 将有助于共享其值,但您将面临另一个问题:对象 X 上的非原子更新,如果字段的值相互依赖。

正如 @alf 指出的,为了从 happens-before 保证中受益,对象必须安全地传递!这可以使用 java.util.concurrent.** 类来实现。像 Akka 这样的高级构造定义了自己的安全“传递”对象的机制。

引用文献:

https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

关于scala - @volatile 用法不清楚 - 将带有 `var` 的对象发送到另一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37305415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com