El punto muerto en Java es parte del subproceso múltiple. El punto muerto puede ocurrir en una situación en la que un subproceso está esperando un bloqueo de objeto adquirido por otro subproceso y el segundo subproceso está esperando un bloqueo de objeto adquirido por el primer subproceso. Dado que ambos subprocesos están esperando que el otro libere el bloqueo, la condición se denomina punto muerto.
Ejemplo de punto muerto en Java
TestDeadlockExample1.java
public class TestDeadlockExample1 { public static void main(String[] args) { final String resource1 = 'ratan jaiswal'; final String resource2 = 'vimal jaiswal'; // t1 tries to lock resource1 then resource2 Thread t1 = new Thread() { public void run() { synchronized (resource1) { System.out.println('Thread 1: locked resource 1'); try { Thread.sleep(100);} catch (Exception e) {} synchronized (resource2) { System.out.println('Thread 1: locked resource 2'); } } } }; // t2 tries to lock resource2 then resource1 Thread t2 = new Thread() { public void run() { synchronized (resource2) { System.out.println('Thread 2: locked resource 2'); try { Thread.sleep(100);} catch (Exception e) {} synchronized (resource1) { System.out.println('Thread 2: locked resource 1'); } } } }; t1.start(); t2.start(); } }
Producción:
Thread 1: locked resource 1 Thread 2: locked resource 2
Puntos muertos más complicados
Un punto muerto también puede incluir más de dos subprocesos. La razón es que puede resultar difícil detectar un punto muerto. A continuación se muestra un ejemplo en el que cuatro subprocesos se han estancado:
El hilo 1 bloquea A, espera a B
El hilo 2 bloquea B, espera C
El hilo 3 bloquea C, espera D
El hilo 4 bloquea D, espera A
El hilo 1 espera al hilo 2, el hilo 2 espera al hilo 3, el hilo 3 espera al hilo 4 y el hilo 4 espera al hilo 1.
¿Cómo evitar un punto muerto?
La solución a un problema se encuentra en sus raíces. En un punto muerto, el problema principal es el patrón de acceso a los recursos A y B. Para resolver el problema, simplemente tendremos que reordenar las declaraciones donde el código accede a recursos compartidos.
DeadlockSolved.java
public class DeadlockSolved { public static void main(String ar[]) { DeadlockSolved test = new DeadlockSolved(); final resource1 a = test.new resource1(); final resource2 b = test.new resource2(); // Thread-1 Runnable b1 = new Runnable() { public void run() { synchronized (b) { try { /* Adding delay so that both threads can start trying to lock resources */ Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } // Thread-1 have resource1 but need resource2 also synchronized (a) { System.out.println('In block 1'); } } } }; // Thread-2 Runnable b2 = new Runnable() { public void run() { synchronized (b) { // Thread-2 have resource2 but need resource1 also synchronized (a) { System.out.println('In block 2'); } } } }; new Thread(b1).start(); new Thread(b2).start(); } // resource1 private class resource1 { private int i = 10; public int getI() { return i; } public void setI(int i) { this.i = i; } } // resource2 private class resource2 { private int i = 20; public int getI() { return i; } public void setI(int i) { this.i = i; } } }
Producción:
In block 1 In block 2
En el código anterior, la clase DeadlockSolved resuelve el tipo de situación de punto muerto. Ayudará a evitar puntos muertos y, en caso de que se produzcan, a resolverlos.
¿Cómo evitar el punto muerto en Java?
Los puntos muertos no se pueden resolver por completo. Pero podemos evitarlos siguiendo las reglas básicas que se mencionan a continuación: