Si el acceso a datos mutables compartidos no se puede sincronizar, las consecuencias pueden ser nefastas, incluso si la variable se puede leer y escribir atómicamente.
Consideremos un problema de sincronización de subprocesos. Para la sincronización de subprocesos, la biblioteca de clases Java proporciona el método Thread.stop, pero no vale la pena promover este método porque es inherentemente inseguro. Sería mejor utilizar encuestas, como el siguiente programa.
Copie el código de código de la siguiente manera:
importar java.util.concurrent.TimeUnit;
clase pública StopThread {
/**
* argumentos @param
*/
stopRequested booleano estático privado;
principal vacío estático público (String [] args)
lanza una excepción interrumpida {
Hilo de fondoThread = nuevo hilo (nuevo Runnable() {
@Anular
ejecución pública vacía() {
int yo = 0;
mientras(!stopRequested){
yo ++;
System.out.println(i);
}
}
});
fondoThread.start();
Unidad de tiempo.SEGUNDOS.dormir(1);
detenerSolicitado = verdadero;
}
}
Puede pensar que después de que este programa se ejecuta durante aproximadamente un segundo, el hilo principal establece stopRequested en verdadero, lo que hace que el nuevo hilo en segundo plano se detenga. De hecho, este no es el caso, porque el hilo en segundo plano no puede ver el cambio en esto. valor, por lo que continuará en bucle sin fin, esta es la consecuencia de no sincronizar los datos. Así que hagamos esto sincrónicamente.
Copie el código de código de la siguiente manera:
importar java.util.concurrent.TimeUnit;
clase pública StopThread {
/**
* argumentos @param
*/
stopRequested booleano estático privado;
requestStop(){ vacío sincronizado estático privado
detenerSolicitado = verdadero;
}
stopRequested booleano sincronizado estático privado(){
retorno stopRequested;
}
principal vacío estático público (String [] args)
lanza una excepción interrumpida {
Fondo del hiloThread = nuevo hilo (nuevo Runnable() {
@Anular
ejecución pública vacía() {
int yo = 0;
mientras(!stopRequested()){
yo ++;
System.out.println(i);
}
}
});
fondoThread.start();
Unidad de tiempo.SEGUNDOS.dormir(1);
solicitarParada();
}
}
Esto logra la sincronización de datos. Vale la pena señalar que tanto el método de escritura (requestStop) como el método de lectura (stopRequested) deben estar sincronizados; de lo contrario, todavía no está sincronizado en el verdadero sentido.
Además, podemos utilizar el modificador de variable volátil para completar las tareas de sincronización de forma más sencilla.
Copie el código de código de la siguiente manera:
importar java.util.concurrent.TimeUnit;
clase pública StopThread {
/**
* argumentos @param
*/
stopRequested booleano volátil estático privado;
principal vacío estático público (String [] args)
lanza una excepción interrumpida {
Fondo del hiloThread = nuevo hilo (nuevo Runnable() {
@Anular
ejecución pública vacía() {
int yo = 0;
mientras(!stopRequested){
yo ++;
System.out.println(i);
}
}
});
fondoThread.start();
Unidad de tiempo.SEGUNDOS.dormir(1);
stopRequested = verdadero;
}
}