java multithreading if-statement switch-statement conditional-statements

java - ¿El operador del interruptor es atómico?



multithreading if-statement (2)

En la documentación se dice que también puede usar if-else varias veces o switch-case :

int condition; setCondition(int condition) { this.condition = condition; }

Cualquiera de los dos casos de cambio

switch (condition) { case 1: print("one"); break; case 2: print("two"); break;

o

if (condition == 1) { print("one"); } else if (condition == 2) { print("two"); }

A continuación, la condition se declara volatile y el método setCondition() se llama desde varios subprocesos. If-else no es atómico y la variable de escritura volatile es una acción de sincronización. Por lo tanto, tanto la cadena "uno" como la "dos" podrían imprimirse en el último código.

Se podría evitar si se utilizara algún método de variable local con valor inicial:

int localCondition = condition; if (local condition == ..) ..

¿El operador de la switch-case tiene alguna copia inicial de la variable? ¿Cómo se implementan las operaciones de subprocesos cruzados con él?


De la especificación de Java en sentencias de conmutación:

Cuando se ejecuta la instrucción switch, primero se evalúa la expresión. [...]

Esto sugiere que la expresión se evalúa una vez y que el resultado se guarda temporalmente en otro lugar, por lo que no son posibles las condiciones de carrera.

Aunque no puedo encontrar una respuesta definitiva en ninguna parte.

Una prueba rápida muestra que este es realmente el caso:

public class Main { private static int i = 0; public static void main(String[] args) { switch(sideEffect()) { case 0: System.out.println("0"); break; case 1: System.out.println("1"); break; default: System.out.println("something else"); } System.out.println(i); //this prints 1 } private static int sideEffect() { return i++; } }

Y de hecho, sideEffect () solo se llama una vez.


La expresión se evalúa una vez al entrar en el interruptor.

El conmutador puede usar el resultado internamente tantas veces como sea necesario para determinar a qué código saltar. Es similar a:

int switchValue = <some expression>; if (switchValue == <some case>) <do something> else if (switchValue == <some other case> <do something else> // etc

En realidad, un conmutador compila una variedad de estilos de código de bytes en función del número de casos y el tipo del valor.

El interruptor solo necesita evaluar la expresión una vez.