NOTA: pregunta no válida - Véase el comentario de @Bukhtoyarov Vladimir
Digamos que tenemos el siguiente código:
public class Main {
private Object monitor = new Object();
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
main.test();
new Thread() {
@Override
public void run() {
try {
main.changeMonitor();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
private void test() throws InterruptedException {
synchronized (monitor) {
Thread.sleep(100);
monitor = new Object();
Thread.sleep(1000);
System.out.println("test finished");
}
}
private void changeMonitor() throws InterruptedException {
Thread.sleep(600);
monitor = new Object();
System.out.println("monitor changed");
}
}
Aquí tenemos dos hilos - hilo principal y otro subproceso de trabajo. También tenemos monitor
objeto. Subproceso de trabajo en el interior tenemos siguiente secuencia de acciones -
- cerradura de adquirir
monitor
- 100 ms de espera
- Asignar referencia monitor a punto un nuevo objeto
- esperar otros 1000ms
En hilo principal estamos a la espera 600ms y tratar de reasignar monitor a un nuevo objeto. Como resultado - hilo principal está bloqueada - hasta comunicados de los subprocesos de trabajo de bloqueo en el monitor
objeto. Aquí tengo dos preguntas
- De acuerdo con el
Concurrency in practice
libro - la única manera de ser bloqueado por el proceso aquision bloqueo - es entrar en bloque de sincronización. Entonces, ¿por hilo principal está bloqueada hasta comunicados de subproceso de trabajo de bloqueo - en el hilo principal no estamos tratando de entrar en el bloque de sincronización - Subproceso de trabajo de asignación de nuevo objeto de
monitor
referencia después de 100 ms, qué hilo principal no puede adquirir el bloqueo nuevo objeto reasignada después de 600 ms? Quiero decir - después de 600 ms enmonitor
árbitro nuevo objeto - de modo de bloqueo debe estar listo para ser adquirida El comportamiento es interesante - como no puedo encontrar ninguna información al respecto en la documentación oficial de Oracle oConcurrency in practice
libro.
este código
synchronized (monitor) {
es como
Object m = monitor;
synchronized (m) {
es decir, la lectura sólo ocurre una vez, y en un contexto que no es seguro para subprocesos.
por eso hilo principal no puede bloquear el nuevo objeto - reasignado subproceso de trabajo en el interior.
Esto significa
- una vez que se ha obtenido un objeto establecer la comunicación con, no siga leyendo el último valor en un bucle para ver si se puede bloquear en otro objeto.
- incluso si se cambia la referencia antes de la lectura, se pudo ver un valor antiguo, ya que la lectura no es seguro para subprocesos.