2012-03-04 11 views
6

Digamos que tengo un hilo conductor de esta manera:valor Obtención de una variable hilo desde fuera

private boolean working = true; 

@Override public void run() { 
    working = true; 
    // do something 
    working = false; 
    .... 
} 

y en mi hilo principal que estoy poniendo constantemente el estado de trabajo con

while(threadClassObject.isWorking()) { 
    System.out.println(threadClassObject.isWorking()); 
} 

¿funcionaría esto? Intenté este ejemplo y parece funcionar. Pero, ¿hay alguna manera de que esto pueda colapsar? Lo que v.g. Qué sucede si el hilo está en el proceso de cambiar de trabajo mientras que al mismo tiempo el hilo principal intenta leerlo?

Respuesta

6

La respuesta a su pregunta es que podría estar funcionando, pero el código anterior es un código arriesgado y puede romperse cualquier día. Trate de hacer workingvolatile como

private volatile boolean working = true; 

What e.g. happens if the thread is in the process of changing working while at the exact same time the mainThread tries to read it?

operación de asignación es una operación atómica. Entonces, si tiene una sola CPU, dos hilos nunca pueden colisionar mientras acceden a la variable. Si tiene más de una CPU, dos hilos pueden colisionar al acceder a la variable. Para ambos casos, volatile se asegurará de que el valor sea visible para otros hilos.

NOTA: volatile es bueno en su situación, pero si tiene datos más complejos a través de compartir hilo try looking into this

Editar:

Agregar el comentario también parte de la Soln. para hacerlo más claro.

Básicamente gracias a la optimización a nivel de cpu, los valores cambiaron y es posible que un hilo no sea visible para otro. Un buen ejemplo es la optimización de la memoria caché de la CPU. Los valores nunca se reflejan en el RAM donde podría estar leyendo el otro subproceso. Volátil dice que el valor de esta variable se puede cambiar fuera del alcance de hilo actual por lo que no tal optimización se realiza ...

+0

Ok gracias por las respuestas chicos, ahora lo han cambiado a volátil. ¿Qué pasaría exactamente si colisionan?Porque ahora he hecho 2 bucles sin fin, uno en el hilo que cambia constantemente la variable de trabajo y otro en el hilo principal que lo comprueba constantemente y no pasa nada. –

+0

Básicamente gracias a la optimización en el nivel de cpu, los valores cambiaron mi único hilo podría no ser visible para otro. Un buen ejemplo es la optimización de la memoria caché de la CPU. Los valores nunca se reflejan en el RAM donde podría estar leyendo el otro subproceso. Volátil dice que el valor de esta variable se puede cambiar fuera del alcance de hilo actual por lo que no tal optimización se realiza ... – havexz

1

Necesitará utilizar sincronización o AtomicBoolean para que sea seguro para subprocesos. Lo que tienes en tu código parecerá funcionar, pero es posible que cuando revises el booleano, no tenga el valor correcto, por lo que verás resultados inesperados.

0

No, no es necesario bloquear tipos primitivos como un booleano. Si 'working' era un objeto, entonces necesitaría usar bloques sincronizados.

+3

Si no es 'volátil',' isValue() 'llamado en el hilo principal no puede ver el valor cambiado. –

+3

No hay peligro de observar un booleano en un estado parcial, pero aún así puede tener problemas: no hay garantía de que el hilo principal _ver_ verá una escritura hecha en el hilo secundario a menos que el programa establezca una relación de pase previo con la escritura y la lectura a través de la sincronización de algún tipo. Esto es independiente de si el trabajo es un objeto o un primitivo. – jacobm

3

También puede ser que desee mirar en hacer algo con su "fuera de control", mientras que en su bucle de hilo principal:

La implementación actual seguirá girando, sin dejar mucho tiempo de CPU para los subprocesos ejecutando run() (o cualquier otra persona en el sistema, para el caso).

+1

Elaborar, '' Thread.sleep' y Thread.yield' son dos formas sencillas de evitar que esto suceda. Una solución más sólida sería reestructurar el programa para que sea impulsado por eventos, o algo así. – Taymon

+0

Gracias, solo hice el ciclo de esa manera para probarlo, así que siempre accedo a la variable de subprocesos. –

Cuestiones relacionadas