java - ¿El operador de preincremento es seguro para subprocesos?
multithreading pre-increment (5)
++ operador no es atómico. Mira aquí http://madbean.com/2003/mb2003-44/ . Para operaciones atómicas puedes usar AtomicInteger
AtomicInteger atomicInteger = new java.util.concurrent.atomic.AtomicInteger(0)
y cada vez que quiera incrementar puede llamar atomicInteger.incrementAndGet()
método atomicInteger.incrementAndGet()
que devuelve una primitiva int. 0 es el valor inicial predeterminado para el número entero atómico.
Estoy haciendo un programa en Java que compite con algunos coches uno contra el otro. Cada automóvil es un hilo separado.
Cuando los autos completan la carrera, cada uno llama a este método. He probado el método a diferentes velocidades de temporizador, y parece funcionar bien. Pero me doy cuenta de que cada hilo está accediendo a la variable carsComplete, a veces exactamente al mismo tiempo (al menos en el alcance que me da el comando date).
Entonces mi pregunta es: ¿este método es seguro para subprocesos?
public static String completeRace()
{
Date accessDate = new Date();
System.out.println("Cars Complete: " + carsComplete + " Accessed at " + accessDate.toString());
switch(++carsComplete)
{
case 1: return "1st";
case 2: return "2nd";
case 3: return "3rd";
default: return carsComplete + "th";
}
}
El AtomicInteger
en int
no es seguro para subprocesos, use AtomicInteger
que no está bloqueado:
AtomicInteger carsComplete = new AtomicInteger();
//...
switch(carsComplete.incrementAndGet())
Por cierto, el código a continuación no es seguro para subprocesos también. ¿Puedes decir por qué?
carsComplete.incrementAndGet();
switch(carsComplete.get())
Lo mismo que en C ++, el operador ++
no es atómico.
En realidad, se están ejecutando más de 1 instrucción bajo el capó (no te dejes engañar al ver un simple ++i
; es load/add/store
) y dado que hay más de 1 instrucción implicada sin sincronización, puedes tener varios intercalados con resultados incorrectos.
Si necesita instalar los carsComplete
de manera segura, puede usar el constructo AtomicInteger
o puede sincronizar todo el método
No, deberías estar usando algo como java.util.concurrent.atomic.AtomicInteger
. Mira su método getAndIncrement()
.
La pregunta es "¿es seguro el hilo del operador pre incremento?"
Respuesta: No, ¿por qué? debido a la cantidad de instrucciones involucradas. Atómico significa operación única, aquí se deben realizar operaciones de carga / adición / almacenamiento. Entonces no es una operación atómica.
Same for post increment.