如果我在某个集合结构中有一个链接节点,我真的不希望它的下一个链接是AtomicReference(我需要原子CAS更新)所以我将它声明为:
@volatile var next: Node[A] = _n
然后在伴侣声明中:
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);
在运行时,我收到以下错误:
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)
...
因此,在运行时,伴随对象为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();
所以,除了在AtomicReferenceFieldUpdater
类上声明的Link
的静态实例外,我已经拥有了所有内容。
问题是,如何在Scala中获得指向易变变量的AtomicReferenceFieldUpdater
实例?
到目前为止,我发现的唯一方法是返回Java(使用下一个Node字段和静态AtomicReferenceFieldUpdater
实现AbstractLink)并从中继承,这很难看。
答案 0 :(得分:4)
硬。由于Scala使字段成为私有字段,并且只有可用的访问方法,因此可能无法实现。
执行此操作时,我最终决定通过使用volatile字段创建Java基类并通过那里进行更新来实现。
Java文件:
public class Base {
volatile Object field = null;
}
Scala文件:
class Cls extends Base {
val updater = AtomicReferenceFieldUpdater.newUpdater(classOf[Base[_]], classOf[Object[_]], "field")
def cas[A](old: Object, n: Object) = updater.compareAndSet(this, old, n);
}
我没有提出不同的方法。
答案 1 :(得分:0)
我被告知在纯scala中无法做到这一点,你需要在Java中定义一个类来执行此操作。幸运的是,交叉编译非常简单,但仍然很烦人!