2009-03-28 14 views
12

¿Hay alguna diferencia en el significado de AtomicIntegerArray y AtomicInteger[]? ¿Y cuál es más rápido de usar? (lo único que noté es que primero está ocupando mucho menos espacio, pero eso significa que cada nueva comprobación está verificando los límites de la matriz, por lo que sería más lento?)AtomicIntegerArray vs AtomicInteger []

Editar: En un escenario donde la matriz es pre inicializado

Respuesta

8

AtomicInteger[] requerirá un objeto por elemento. AtomicIntegerArray solo requiere el objeto AtomicIntegerArray y un objeto de matriz. Entonces usa el último si es posible.

El costo de comprobación de límites es bastante pequeño incluso para matrices normales. Lo que podría ser significativo es que el acceso a datos en la misma línea de caché de múltiples procesadores puede causar problemas de rendimiento significativos. Por lo tanto, separar objetos, o evitar deliberadamente elementos cercanos de una matriz, puede ayudar.

+0

¿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). –

+0

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

+0

(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. –

0

Estoy de acuerdo con el párrafo primero de Tom Hawin ...

AtomicInteger [] requerirá un objeto por elemento. AtomicIntegerArray solo requiere el objeto AtomicIntegerArray y un objeto de matriz. Entonces usa el último si es posible.

... pero también debe tenerse en cuenta que AtomicInteger [] no es seguro para subprocesos. Específicamente, las referencias de la matriz a los objetos AtomicInteger individuales pueden o no ser correctas si se accede desde múltiples hilos. Sin embargo, sincronizar el acceso en el objeto de matriz eliminará este problema.

+2

El punto sobre Atomic * es que evitas la sincronización. El supuesto método de uso de AtomicInteger [] es crear todos los AtomicIntegers una sola vez y solo luego publicar la matriz de forma segura. –

+1

Estoy de acuerdo. No estoy defendiendo el uso de AtomicInteger [], solo notando la diferencia, que es de lo que se trataba la pregunta :) –

4
  • AtomicInteger [] es una matriz de enteros de seguridad de rosca.
  • AtomicIntegerArray es una matriz segura de subprocesos de enteros.
2

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.

+0

Al precio de menor velocidad para las operaciones de actualización (aunque get y set son rápidos). A veces vale la pena extenderlo desde Atomic * como un truco de ahorro de memoria. –

Cuestiones relacionadas