threads thread programacion hilos examples example ejercicios ejemplo concurrente concurrencia atomicas java multithreading for-loop while-loop synchronized

java - thread - ¿Puedo sincronizar lecturas de variables de control?



variables atomicas java (3)

si solo está restableciendo el valor de running una vez para designar para detenerse, es posible que pueda usar la palabra clave volatile .

Sin embargo, si necesita iniciar y detener muchas veces, esto no funcionará. Esto se debe a que los campos volátiles "pueden perder una actualización"

Aquí hay un enlace a la explicación de cuándo funciona el volatile en casos como este enlace

aquí está el ejemplo de código de ese enlace en caso de que se muera:

public class StoppableTask extends Thread { private volatile boolean pleaseStop; public void run() { while (!pleaseStop) { // do some stuff... } } public void tellMeToStop() { pleaseStop = true; } }

Si necesita iniciar y detener muchas veces, entonces necesita usar uno de los objetos de bloqueo concurrente de Java 5 o sincronización explícita

El siguiente código funcionará, pero me molesta un poco tener que escribir el método isRunning ():

class Test { private boolean running; public void startX() { synchronized(this) { running = true } while (isRunning()) { //do something } } public synchronized void stopX() { running = false; } private synchronized boolean isRunning() { return running; } }

¿Puedo sincronizar las lecturas de la variable en running en el while (running){} de alguna otra manera, o tengo que escribir el método isRunning ()? La misma pregunta se aplica también a otras variables de control, p. Ej.

for (;running;) {}

o

if (running) {}

En todos estos casos, parece como si estuvieras obligado a escribir un método sin sentido para corregir la sincronización. ¿Me estoy perdiendo de algo?


solo para sumarle a la respuesta de otras personas que sugería volatile . Alternativamente, podría crear una clase para los controles. He hecho que la variable sea static , por lo que todos los hilos estarán apuntando al mismo objeto.

class Runner{ boolean static running=true; public static synchronized boolean getRunning(){ return running; } public static synchronized boolean setRunning(boolean r){ running=r; } }

NOTA:

si no necesita la variable global, elimine la static


Puede hacer que el campo de ejecución sea volátil. Al hacer que el campo sea volátil, se le avisa a la JVM que debe hacer cambios en ese campo visible para otros hilos. La advertencia de "omita una actualización" es para los casos en los que desea leer un valor y actualizar según ese valor, que no parece aplicable aquí. Múltiples hilos pueden escribir en este campo, si todo lo que hacen es establecer un indicador booleano, entonces esto no será un problema.

Alternativamente, si está intentando cancelar un hilo, ya hay un indicador equivalente provisto en el hilo para esto (y el problema de visibilidad se soluciona). Puede invocar interrupción en un hilo, el código en Runnable puede consultar Thread.currentThread().isInterrupted() para saber si ha sido interrumpido. Esto es preferible a usar su propia bandera porque la interrupción hará que el hilo se active si está esperando o durmiendo. Con su propia bandera, debe esperar hasta que el control llegue a un lugar donde pueda probarse la bandera.