2012-04-19 14 views
6

Según lo que entiendo, el siguiente fragmento de código debe provocar un interbloqueo. El motivo es que cuando el hilo t1 bloquea el objeto estático firstData, ha adquirido un bloqueo en la clase. Entonces, cuando intente bloquear otro objeto estático secondData, la solicitud debería bloquearse.Bloqueo de miembros estáticos de una clase

Sin embargo, el programa se ejecuta bien y grabados *** Successfully acquired both the locks

¿Qué pasa con cierre para objetos estáticos que Im que falta aquí?

public class Deadlock { 
    public static void main(String[] args) { 

     Thread t1 = new Thread(new DeadlockRunnable()); 
     t1.start(); 
    } 
} 

class DeadlockRunnable implements Runnable { 
    static Object firstData = new Object(); 
    static Object secondData = new Object(); 

    public void run() { 
     synchronized(firstData) { 
      synchronized(secondData) { 
       System.out.println("*** Successfully acquired both the locks"); 
      } 
     } 
    } 

} 

Para todos aquellos que respondieron que los bloqueos son el objeto, en lugar de la clase, por favor, eche un vistazo a this

Respuesta

14

En primer lugar, usted tiene un error aquí:

La razón de ser , cuando el hilo t1 bloquea el objeto estático firstData, ha adquirido un bloqueo en la clase.

El bloqueo de un objeto estático solo bloquea ese objeto, no la clase. Usted está bloqueando dos objetos separados.

El question you refered to es aproximadamente synchronized methods no synchronized statements. Estas dos construcciones relacionadas funcionan de maneras ligeramente diferentes.


En segundo lugar, incluso si se cerraban sobre el mismo objeto, su código seguiría sin punto muerto (ideone). Los bloqueos intrínsecos son reentrantes. Esto significa que un subproceso no se bloquea por sí mismo si intenta tomar el mismo bloqueo dos veces.

Reentrante sincronización

Recordemos que un hilo no puede adquirir un bloqueo propiedad de otro hilo. Pero un hilo puede adquirir un bloqueo que ya posee. Permitir que un hilo adquiera el mismo bloqueo más de una vez habilita la sincronización de reentrada. Esto describe una situación en la que el código sincronizado, directa o indirectamente, invoca un método que también contiene código sincronizado, y ambos conjuntos de código utilizan el mismo bloqueo. Sin la sincronización de reentrada, el código sincronizado debería tomar muchas precauciones adicionales para evitar que un tema se bloquee.

Source

+1

Además, un solo hilo nunca producirá un interbloqueo. –

+0

El siguiente enlace me hizo creer así: http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class –

+0

Estoy de acuerdo con @KirkWoll. Pero tengo una pregunta. Entonces, ¿eso significa que un hilo puede bloquear múltiples objetos estáticos al mismo tiempo? – noMAD

1

"cuando el objeto cerraduras t1 hilo estática FirstData, que ha adquirido un bloqueo en la clase"
No estoy seguro de por qué piensa así. t1 adquiere un bloqueo en firstData, no en la clase contenedora. No hay un posible punto muerto en su código tal como está.

EDITAR
Tras su comentario, el enlace es sobre la diferencia entre las 2 declaraciones:

public synchronized method() // lock on the instance (this) 
public static synchronized method() // lock on the class (Myclass.class) 

Pero no existe un vínculo con los puntos muertos.

+0

El siguiente enlace me hizo creer que http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class –

+0

@assylias: ¿Podría explicar qué objeto se bloquea cuando t1 adquiere bloquear en 'firstData' (campo estático) ... ¿quería decir que solo el Object firstData se bloquea? ... ¿Ni la clase ni el contenedor objeto DeadlockRunnable? –

+0

@ tm.sauron Sí, una cerradura está atada a un objeto específico, en este caso 'firstData' y' secondData'; la clase adjunta 'DeadlockRunnable' no tiene otra función que la de un contenedor de código aquí ... – assylias

Cuestiones relacionadas