If I have a linked node in some kind of collection structure, I don't want its next link to be AtomicReference (I need atomic CAS update), so I declare it as:
@volatile var next: Node[A] = _n
and then in the companion declare:
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);
At runtime, I get the following error:
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)
...
So, at run time, the companion object is concurrent.Link$not concurrent.Link, and the other class cannot access the private member of the other.
BUT if I javap -p concurrent.Link
I get:
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();
So, I have everything except the static instance AtomicReferenceFieldUpdaterdeclared in my class Link.
The question is how to get an instance AtomicReferenceFieldUpdaterin Scala that points to volatile var?
, , - Java ( AbstractLink node AtomicReferenceFieldUpdater) , .