2012-04-28 15 views
15

Vi esto en uno de Heinz Kabutz Java Specialist ediciones del boletín y, aunque el resto (y, de hecho, todos) de los artículos del Dr. Kabutz están bien explicados y detallados, parecía pasar por alto lo que este código está haciendo, o más importante, lo que ha significado es:Java: bloques de sincronización anidados

public class SomeObject { 
    private Object lock1; 
    private Object lock2; 

    public void doSomething() { 
     synchronized(lock1) { 
      synchronized(lock2) { 
       // ... 
      } 
     } 
    } 
} 

¿Cuáles son las implicaciones de anidación synchronized bloques? ¿Cómo afecta esto a los diferentes hilos que intentan doSomething()?

+0

En este escenario, todos los hilos se bloquearían en el candado exterior, hasta que se soltó por el hilo en el candado interno. –

+2

El snippit que has publicado no hace nada; el único hilo que puede tener 'lock2' es el que tiene' lock1'. Sin saber qué es el resto del código y para qué se usan esos bloqueos, es imposible responder. –

+0

¿Qué artículo estabas leyendo? – Jeffrey

Respuesta

27

Hay 2 temas posibles que uno tendría que mirar hacia fuera para

  1. cerraduras anidada puede provocar bloqueos con bastante facilidad si se está utilizando de espera/notificar. Aquí hay una explicación de por qué. http://tutorials.jenkov.com/java-concurrency/nested-monitor-lockout.html

  2. Hay que tener cuidado con que si otro método desea bloquear las mismas dos objetos, que siempre deben hacerlo en el mismo orden, si no existe la posibilidad de otra situación de bloqueo, como se explica en este post: How to avoid Nested synchronization and the resulting deadlock

+1

¿Podría preguntar si hay alguna solución para el bloqueo del monitor anidado? ¿Es posible esperar en el bloqueo interno y el bloqueo externo o no hay forma de hacerlo? –

+0

Deadlock requiere 4 condiciones previas. Exclusión mutua (por lo tanto, sincronización (nodos) {sincronización (bordes) {}}, mientras que otra función tiene sincronización (bordes) {sincronización (nodos) {}}), no se puede usar con anticipación, espera circular y retención de recursos. Solo tener exclusión mutua no es suficiente para que haya un punto muerto. Estas son llamadas las condiciones de Coffman si tienes curiosidad. http: //en.wikipedia.org/wiki/Deadlock_prevention_algorithms –

1

Por sí solo este fragmento de código no causará ningún problema. Pero el problema puede venir en forma de interbloqueo si hay algo como este código; donde tenemos dos métodos con bloques sincronizados de tal manera que los objetos están encerrados en orders- opuesto

public void doSomething() { 
    synchronized(lock1) { 
     synchronized(lock2) { 
      // ... 
     } 
    } 
} 

public void doOtherthing() { 
    synchronized(lock2) { 
     synchronized(lock1) { 
      // ... 
     } 
    } 
} 

ahora si más de un hilo está intentando acceder a estos métodos, entonces puede haber un punto muerto a causa de bloques sincronizados anidados .

0

Según Nested Monitor Lockout Tutorial

En bloqueo monitor de anidado, hilo 1 se mantiene un bloqueo A, y espera para una señal de Thread 2. Hilo 2 necesita la cerradura A para enviar la señal para enhebrar 1 Mientras está en punto muerto, dos hilos esperan el uno al otro para liberar bloqueos.

Deadlock podría ser análogo a dos personas encarceladas en dos habitaciones, quieren hacer un cambio a la habitación del otro, pero las dos solo tienen la clave de su contraparte. Mientras el monitor está anidado, el jefe está dispuesto a dormir en una habitación y supongo que lo despertarán solo cuando alguien entre en la habitación. Y el secretario es responsable de despertar a su jefe. Pero el jefe todavía tenía la llave de la habitación cuando dormía, por lo que la secretaria no podía entrar para despertarlo.

Cuestiones relacionadas