Debajo, AtomicInteger y AtomicIntegerArray suelen utilizar las mismas API de bajo nivel para realizar lecturas, escrituras y otras operaciones de CAS. (Por ejemplo, OpenSDK 7 usa sun.misc.Unsafe
para realizar las operaciones CAS en ambas clases). Por lo tanto, hay poco rendimiento en el uso de AtomicInteger []. Como ya ha notado, el uso de AtomicIntegerArray tiene tiene importantes ventajas de memoria.
En una nota práctica, el uso del último le libera de tener que construir todas sus instancias AtomicInteger, también. Recuerda que no puedes asignar ingenuamente a esos personajes por pereza debido a razones de concurrencia; deberá preasignar o utilizar algún mecanismo de publicación seguro. Entonces, además de las ventajas de memoria, su código es más limpio.
En una línea similar, si usted tiene un montón de objetos con los miembros AtomicInteger, por ejemplo:
class ReadCounter {
private final String _fileName;
private final AtomicInteger _readCount;
...
}
private final Map<String, ReadCounter> _counterByName = ...;
entonces puede obtener mejoras memoria similares mediante el modelado de la variable miembro _readCount
como volatile int
y el uso de AtomicIntegerFieldUpdater
.
¿A quién le importan los controles de límites? Si nos fijamos en el código fuente (aparente) para, digamos, getAndSet, hace el cálculo de la dirección tanto para get como para compareAndSet (aunque peor que esto, la mayoría de los procesadores pueden hacer get-set sin cas). –
tnx (no vi tu segundo párrafo ahí) ¿Entonces sería bueno no crear todos los objetos al mismo tiempo? (o con alguna orden al azar?) – Sarmun
(Hice una edición rápida.) Crear objetos en diferentes momentos no ayudará ya que el GC los reorganizará. Una de las clases en java.util.concurrent llega a agregar muchos rellenos (en versiones recientes). Debería ser más fácil y más claro agregar elementos de relleno a AtomicIntegerArray, simplemente desplácese hacia la izquierda. –