initialize how ejemplo atomicinteger java atomic java.util.concurrent

how - atomicinteger java ejemplo



AtomicInteger.incrementAndGet() versus AtomicInteger.getAndIncrement() (5)

Aquí estoy dando un ejemplo. Espero que se aclaren tus dudas.

Supongamos que tengo una variable como

AtomicInteger i = nuevo AtomicInteger ();

En este caso:

i.getAndIncrement () <==> i ++;

Y

i.incrementAndGet () <==> ++ i;

Por favor, eche un vistazo a los siguientes programas

public class Test1 { public static void main(String[] args) { AtomicInteger i = new AtomicInteger(); System.out.println(i.incrementAndGet()); System.out.println(i); } }

**salida

1 1 ====================================== **

public class Test2 { public static void main(String[] args) { AtomicInteger i = new AtomicInteger(); System.out.println(i.getAndIncrement()); System.out.println(i); } }

**salida

0 1 ------------- **

Comentario: 1) En la clase Test1, incrementAndGet () primero incrementará el valor iy luego imprimirá.

2) En la clase Test2, getAndIncrement () imprimirá primero el valor iy luego incrementará.

Eso es todo.

Cuando el valor de retorno no es de interés, ¿hay alguna diferencia (incluso irrelevante en la práctica) entre los AtomicInteger.getAndIncrement() y AtomicInteger.incrementAndGet() , cuando se ignora el valor de retorno?

Estoy pensando en diferencias como las que serían más idiomáticas, así como las que pondrían menos carga en los cachés de CPU que se sincronizarían, o cualquier otra cosa realmente, cualquier cosa para ayudar a decidir cuál usar más racionalmente que lanzar una moneda.


Dado que no se ha dado respuesta a la pregunta real, esta es mi opinión personal basada en las otras respuestas (agradecimientos, upvoted) y la convención de Java:

incrementAndGet()

es mejor, porque los nombres de los métodos deberían comenzar con el verbo que describe la acción, y la acción que se pretende aquí es solo aumentar.

Comenzar con el verbo es la convención común de Java, también descrita por los documentos oficiales:

"Los métodos deben ser verbos, en caso mixto con la primera letra en minúscula, con la primera letra de cada palabra interna en mayúsculas".


El código es esencialmente el mismo por lo que no importa:

public final int getAndIncrement() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return current; } } public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }


No, no hay diferencia (si no te importa el valor de retorno).

El código de esos métodos (en OpenJDK) difiere solo en que uno usa return next y el otro usa return current .

Ambos usan compareAndSet bajo el capó con el mismo algoritmo exacto. Ambos necesitan saber tanto el valor antiguo como el nuevo.


Solo quiero agregar respuestas existentes: podría haber una diferencia muy pequeña e imperceptible.

Si miras esta implementación :

public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); } public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; }

Nota: ambas funciones llaman exactamente a la misma función getAndAddInt , excepto la parte +1 , lo que significa que en esta implementación, getAndIncrement es más rápido.

Pero, aquí hay una implementación más antigua :

public final int getAndIncrement() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return current; } } public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }

La única diferencia es la variable de retorno, por lo que ambas funciones realizan exactamente lo mismo.