如何从scala配套对象获取AtomicReferenceFieldUpdater?

Jed*_*ith 5 concurrency scala java.util.concurrent

如果我在某个集合结构中有一个链接节点,我真的不希望它的下一个链接是AtomicReference(我需要原子CAS更新)所以我将它声明为:

@volatile var next: Node[A] = _n
Run Code Online (Sandbox Code Playgroud)

然后在同伴声明:

val updater = AtomicReferenceFieldUpdater.newUpdater(classOf[Link[_]], classOf[Node[_]], "n")
def cas[A](target: Link[A], old: Node[A], newNode: Node[A]) = updater.compareAndSet(target, old, newNode);
Run Code Online (Sandbox Code Playgroud)

在运行时,我收到以下错误:

java.lang.RuntimeException: java.lang.IllegalAccessException: 
  Class concurrent.Link$ can not access a member of class concurrent.Link
  with modifiers "private volatile"
    at java.util.concurrent.atomic.AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.<init>(AtomicReferenceFieldUpdater.java:189)
    at java.util.concurrent.atomic.AtomicReferenceFieldUpdater.newUpdater(AtomicReferenceFieldUpdater.java:65)
    at concurrent.Link$.<init>(Link.scala:106)
    ...
Run Code Online (Sandbox Code Playgroud)

因此,在运行时,伴随对象concurrent.Link$不是,concurrent.Link并且不同的类不能访问另一个的私有成员.

但是,如果我 javap -p concurrent.Link

我明白了:

Compiled from "Link.scala"
public final class concurrent.Link implements concurrent.Node,scala.ScalaObject,scala.Product,java.io.Serializable{
private final java.lang.Object value;
private volatile com.atlassian.util.scala.concurrent.Node node;
public static final boolean cas(com.atlassian.util.scala.concurrent.Link, com.atlassian.util.scala.concurrent.Node, com.atlassian.util.scala.concurrent.Node);
public static final java.util.concurrent.atomic.AtomicReferenceFieldUpdater updater();
Run Code Online (Sandbox Code Playgroud)

所以,除了AtomicReferenceFieldUpdaterLink班上声明的静态实例外,我还有其他东西.

问题是,如何AtomicReferenceFieldUpdater在Scala中获得指向volatile变量的实例?

到目前为止,我发现的唯一方法是返回Java(使用下一个Node字段和静态实现AbstractLink AtomicReferenceFieldUpdater)并从中继承,这很丑陋.

Jed*_*ith 0

我被告知在纯 scala 中无法做到这一点,您需要在 Java 中定义一个类来做到这一点。幸运的是,交叉编译非常简单,但仍然很烦人!