package ar.com.javacuriosities.threads; /* * Cuando nos encontramos con un deadlock podemos usar algunas utilidades * para analizar el problema y resolverlo. * * jvisualvm: Utilitario incluido en el JDK el cual nos permite varios analices entre ellos ver el estado de cada Thread * jmc: Utilitario incluido en el JDK el cual nos permite varios analices entre ellos ver el estado de cada Thread, es gratuito para desarrollo pero no para produccion * * Independientemente de las herramientas que usemos lo ideal sera conseguir un Thread Dump lo cual es un volcado con las información de lo que estaba haciendo cada Thread. * Para esto podemos usar alguna de las herramientas solicitadas o jstack la cual viene incluida en el JDK y genera esta información */ public class Lesson14DeadLock { // Definimos dos objetos que vamos a usar como candados private final Object mutex1 = new Object(); private final Object mutex2 = new Object(); public static void main(String[] args) { // Creamos la clase que ejecuta un proceso que genera un Deadlock Lesson14DeadLock test = new Lesson14DeadLock(); // Ejecutamos el método que genera el DeadLock test.deadLock(); } private void deadLock() { Thread t1 = new Thread(new Locking12(this)); Thread t2 = new Thread(new Locking21(this)); t1.start(); t2.start(); } private void lock12() { System.out.println("Thread 1 is waiting for monitor 1"); synchronized (mutex1) { System.out.println("Thread 1 has monitor 1"); System.out.println("Thread 1 sleep"); sleep(); System.out.println("Thread 1 wake up"); System.out.println("Thread 1 is waiting for monitor 2"); synchronized (mutex2) { System.out.println("Thread 1 has monitor 2"); System.out.println("Thread 1 sleep"); sleep(); System.out.println("Thread 1 wake up"); } } } private void lock21() { System.out.println("Thread 2 is waiting for monitor 2"); synchronized (mutex2) { System.out.println("Thread 2 has monitor 2"); System.out.println("Thread 2 sleep"); sleep(); System.out.println("Thread 2 wake up"); System.out.println("Thread 2 is waiting for monitor 1"); synchronized (mutex1) { System.out.println("Thread 2 has monitor 1"); System.out.println("Thread 2 sleep"); sleep(); System.out.println("Thread 2 wake up"); } } } private void sleep() { try { Thread.sleep(1); } catch (InterruptedException e) { // Log and Handle exception e.printStackTrace(); } } private static final class Locking12 implements Runnable { private Lesson14DeadLock deadLock; public Locking12(Lesson14DeadLock deadLock) { this.deadLock = deadLock; } @Override public void run() { deadLock.lock12(); } } private static final class Locking21 implements Runnable { private Lesson14DeadLock deadLock; public Locking21(Lesson14DeadLock deadLock) { this.deadLock = deadLock; } @Override public void run() { deadLock.lock21(); } } }