Anuncios

Bienvenidos sean a este post, hoy hablaremos sobre una situacion que puede suceder con dos o mas threads o procesos que es la posibilidad de que ambas se bloqueen para siempre esperandose uno al otro a esta situacion se le llama Deadlock, podriamos decir bloqueo mortal, esta condicion puede suceder cuando utilicemos multithreads o multiprocesos, aun con el uso de synchronized, para estudiarlo veamos el siguiente ejemplo donde se producira la falla:

TestThread.java

public class TestThread
{
        public static Object Lock1 = new Object();
        public static Object Lock2 = new Object();

        public static void main(String[] args)
        {
                ThreadDemo1 T1 = new ThreadDemo1();
                ThreadDemo2 T2 = new ThreadDemo2();
                T1.start();
                T2.start();
        }

        private static class ThreadDemo1 extends Thread
        {
                public void run()
                {
                        synchronized(Lock1)
                        {
                                System.out.println("Thread 1: "
                                        + "Reteniendo a Lock1...");
                                try { Thread.sleep(10); }
                                catch (InterruptedException e) {}
                                System.out.println("Thread 1: "
                                        + "Esperando a Lock2...");
                                synchronized (Lock2)
                                {
                                System.out.println("Thread 1: "
                                        + "Reteniendo a Lock1 y Lock2");
                                }
                        }
                }
        }

        private static class ThreadDemo2 extends Thread
        {
                public void run()
                {
                        synchronized (Lock2)
                        {
                                System.out.println("Thread 2: "
                                        + "Reteniendo a Lock2...");
                                try { Thread.sleep(10); }
                                catch (InterruptedException e) {}
                                System.out.println("Thread 2: "
                                        + "Esperando por Lock1...");
                                synchronized(Lock1)
                                {
                                System.out.println("Thread 2: "
                                        + "Reteniendo a Lock1 y Lock2");
                                }
                        }
                }
        }
}
Anuncios

En este ejemplo crearemos dos clases dentro de nuestro programa, primero crearemos nuestro main() pero primero crearemos dos objetos llamados Lock1 y Lock2 de tipo Object los cuales los utilizaremos en las otras clases, volviendo al main() crearemos dos objetos de tipo ThreadDemo1 y ThreadDemo2 llamados T1 y T2 respectivamente, para luego iniciarlo. Lo siguiente sera una clase una llamada ThreadDemo1 el cual extiende a la clase Thread, en este caso tendremos un metodo llamado run() al cual le crearemos un bloque synchronized para Lock1, dentro de este bloque primero mostraremos un mensaje relacionado al Thread 1 y el Lock 1, despues tendremos un bloque try/catch en el cual pausaremos 10 segundos al Thread de turno, despues mostraremos otro mensaje, para luego crear otro bloque synchronized pero para el objeto Lock2 donde mostraremos un mensaje, la clase ThreadDemo2 es similar al anterior pero la unica diferencia es que el primer bloque synchronized es para el objeto Lock2 y el segundo synchronized sera para el objeto Lock1 la funcionalidad es la misma pero solo cambian ligeramente los mensajes, para cada uno de los threads creados, si lo compilamos y ejecutamos nos ocurrira lo siguiente:

Anuncios

Como pueden ver quedara en un eterno bucle que solamente puede ser interrumpido por medio de Ctrl+C y esto debido a que ambos procesos (Threads) quedan esperandose uno al otro, para solucionar esto debemos hacer unas simples modificaciones y estas deben ser en la clase ThreadDemo2 donde cambiaremos la siguiente linea:

synchronized (Lock2)

Por esta:

synchronized (Lock1)

Y la otra linea de synchronized dentro del bloque:

synchronized (Lock1)

Por esta otra:

synchronized (Lock2)

Con estas dos modificaciones si volvemos a compilar nuestro programa y lo probamos obtendremos la siguiente salida

Anuncios

En este caso el programa se ejecuto correctamente y no obtuvimos ninguna falla y esto fue gracias a un simple orden a la hora de llamar a nuestro procesos (threads) para que se sincronicen correctamente, aunque si bien este ejemplo fue bastante basico tengan en cuenta este simple detalle a la hora de tener muchos mas procesos simultaneos para evitar bloqueos que pueden no ser notificados por nuestro compilador porque son errores mas de tipo logico y humanos que de sintaxis o mal uso como lo que puede detectar.

Anuncios

En resumen, hoy hemos visto una posible falla a la hora de trabajar con multithreading (multiprocesos), hemos visto un ejemplo simple pero que puede bloquear nuestro programa, hemos visto como solucionarlo y la causa de la falla, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00