如何从scala配套对象获取AtomicReferenceFieldUpdater?
发布时间:2020-12-16 18:37:31 所属栏目:安全 来源:网络整理
导读:如果我在某个集合结构中有一个链接节点,我真的不希望它的下一个链接是AtomicReference(我需要原子CAS更新)所以我将它声明为: @volatile var next: Node[A] = _n 然后在同伴声明: val updater = AtomicReferenceFieldUpdater.newUpdater(classOf[Link[_]],c
如果我在某个集合结构中有一个链接节点,我真的不希望它的下一个链接是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 $not 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(); 所以,我在Link类上声明了AtomicReferenceFieldUpdater的静态实例. 问题是,如何在Scala中获得指向易失性var的AtomicReferenceFieldUpdater实例? 到目前为止,我发现的唯一方法是返回Java(使用下一个Node字段和静态AtomicReferenceFieldUpdater实现AbstractLink)并从中继承,这很难看. 解决方法
硬.由于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,n); } 我没有想出一个不同的方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |