Me gustaría mejorar mi referencia atómicamente. Por ejemplo, para su uso compareAndSet
, getAndSet
y otras operaciones atómicas.
Vine de C ++, por lo que en C ++ Tengo volatile
palabra clave y diferentes características intrínsecas atómicas, o la <atomic>
API . En Java, también hay una volatile
palabra clave y diferentes operaciones atómicas inseguras .
Por cierto, también hay una bien documentada AtomicReference (así como Long
, Integer
, Boolean
), por lo JDK creadores nos ha proporcionado una manera de ejecutar con seguridad las operaciones atómicas contra referencias y primitivas. No hay nada malo acerca de la API, que es rico y parece muy familiar.
Sin embargo, también hay un AtomicReferenceFieldUpdater whick proporciona una manera un poco raro para ejecutar operaciones atómicas: hay que "encontrar" el campo a través de la reflexión por su nombre y entonces se puede usar exactamente las mismas operaciones.
Así que mis preguntas son:
- ¿Cuál es la finalidad de
AtomicReferenceFieldUpdater
todo? En mi opinión, es implícito y un poco extraño: tiene que declarar una variable volátil presentada Y y el campo de actualización en sí. Entonces, ¿dónde debería usar unaFieldUpdater
? - Proporciona una vía indirecta: usted está manipulando (no cambiar !) El
FieldUpdater
, no la variable, esto confunde. - Rendimiento: por lo que yo sé, tanto
AtomicReferenceFieldUpdater
yAtomicReference
están delegando en el inseguro, por lo que su rendimiento es similar, pero de todos modos: ¿existen penalizaciones en el rendimiento deFieldUpdater
Agaist de referencia?
Se utiliza para ahorrar memoria.
Ejemplo de la doc:
class Node {
private volatile Node left, right;
private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
Node getLeft() { return left; }
boolean compareAndSetLeft(Node expect, Node update) {
return leftUpdater.compareAndSet(this, expect, update);
}
// ... and so on
}
declara left
y right
como Node
directamente. Y el AtomicReferenceFieldUpdater
es static final
.
Sin AtomicReferenceFieldUpdater
, puede que deba declarar como AtomicReference<Node>
.
private AtomicReference<Node> left, right;
que consume más memoria queNode
. Cuando hay muchos casos de Node
, consume mucha más memoria que la primera aproximación.