¿Cómo resolver interbloqueos usando subprocesos en Java?

Si dos subprocesos se esperan el uno al otro para siempre, este tipo de espera infinita se denomina interbloqueo en Java . La palabra clave sincronizada es la única razón de la situación de interbloqueo, por lo tanto, al usar la palabra clave sincronizada, debemos tener especial cuidado. No existe una técnica de resolución para el interbloqueo, pero hay varias técnicas de prevención disponibles. 

Implementación: se produce interbloqueo

Ejemplo 1:

Java

// Java program to illustrate Deadlock
// where deadlock occurs
 
// Importing required packages
import java.io.*;
import java.util.*;
 
// Class 1
// Helper class
class A {
 
    // Method 1 of this class
    // Synchronized method
    public synchronized void last()
    {
 
        // Print and display statement
        System.out.println("Inside A, last() method");
    }
 
    // Method 2 of this class
    // Synchronized method
    public synchronized void d1(B b)
    {
        System.out.println(
            "Thread1 start execution of d1() method");
 
        // Try block to check for exceptions
        try {
 
            // Putting the current thread to sleep for
            // specific time using sleep() method
            Thread.sleep(2000);
        }
 
        // Catch block to handle the exceptions
        catch (InterruptedException e) {
            // Display the exception on the console
            System.out.println(e);
        }
 
        // Display statement
        System.out.println(
            "Thread trying to call B's last() method");
 
        // Calling the method 1 of this class as created
        // above
        b.last();
    }
}
 
// Class 2
// Helper class B
class B {
 
    // Method 1 of this class
    public synchronized void last()
    {
 
        // Display statement only
        System.out.println("Inside B, last() method");
    }
 
    // Method 2 of this class
    // Synchronized the method d2
    public synchronized void d2(A a)
    {
 
        // Display message only
        System.out.println(
            "Thread2 start execution of d2() method");
 
        // Try block to check for exceptions
        try {
 
            // Putting the current thread to sleep for
            // certain time using sleep() method
            Thread.sleep(2000);
 
            // Catch block to handle the exceptions
        }
        catch (InterruptedException e) {
 
            // Display the exception on the console
            System.out.println(e);
        }
 
        // Display message only
        System.out.println(
            "Thread2  trying to call A's last method");
 
        // Again calling the last() method inside this class
        a.last();
    }
}
 
// Class 3
// Main class
// Deadlock class which is extending Thread class
class GFG extends Thread {
 
    // Creating object of type class A
    A a = new A();
 
    // Creating object of type class B
    B b = new B();
 
    // Method 1
    public void m1()
    {
 
        // Starting the thread
        this.start();
 
        // Calling d1 method of class A
        a.d1(b);
    }
 
    // Method 2
    // run() method for the thread
    public void run()
    {
 
        // Calling d2 method of class B
        b.d2(a);
    }
 
    // Method 3
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating object of this class
        GFG deadlock = new GFG();
 
        // Calling m1 method
        deadlock.m1();
    }
}

Producción:

Explicación de salida:

Aquí el cursor se muestra para siempre porque los subprocesos entran en una situación de interbloqueo. En el programa anterior, si eliminamos al menos una palabra clave sincronizada, el programa no entrará en la situación de interbloqueo. Por lo tanto, la palabra clave sincronizada es una de las principales razones de la situación de punto muerto. Debido a esto, al usar la palabra clave sincronizada, debemos tener especial cuidado.

Podemos evitar la situación de Deadlock de las siguientes maneras:

  • Uso del método Thread.join() : podemos obtener un interbloqueo si dos subprocesos están esperando el uno al otro para terminar indefinidamente usando la combinación de subprocesos. Luego, nuestro subproceso tiene que esperar a que finalice otro subproceso, siempre es mejor usar el método Thread.join() con el tiempo máximo que desea esperar para que finalice el subproceso.
  • Usar ordenamiento de candados: Siempre tenemos que asignar un valor numérico a cada candado y antes de adquirir el candado con un valor numérico más alto tenemos que adquirir los candados con un valor numérico más bajo.
  • Evitar bloqueos innecesarios: debemos usar bloqueos solo para aquellos miembros en los que se requiere, el uso innecesario de bloqueos conduce a una situación de interbloqueo. Y se recomienda utilizar una estructura de datos sin bloqueos y, si es posible, mantener el código libre de bloqueos. Por ejemplo, en lugar de usar ArrayList sincronizado, use ConcurrentLinkedQueue.

Ejemplo 2: se evita el interbloqueo

Java

// Java program to illustrate Deadlock
// where deadlock is prevented from occurring
 
// Importing required packages
import java.io.*;
import java.util.*;
 
// Class 1
// Helper class
class A {
 
    // Method 1 of this class
    // Synchronized method
    public synchronized void last()
    {
 
        // Print and display statement
        System.out.println("Inside A, last() method");
    }
 
    // Method 2 of this class
    // Synchronized method
    public synchronized void d1(B b)
    {
        System.out.println(
            "Thread1 start execution of d1() method");
 
        // Try block to check for exceptions
        try {
 
            // Putting the current thread to sleep for
            // specific time using sleep() method
            Thread.sleep(2000);
        }
 
        // Catch block to handle the exceptions
        catch (InterruptedException e) {
            // Display the exception on the console
            System.out.println(e);
        }
 
        // Display statement
        System.out.println(
            "Thread trying to call B's last() method");
 
        // Calling the method 1 of this class as created
        // above
        b.last();
    }
}
 
// Class 2
// Helper class B
class B {
 
    // Method 1 of this class
    public void last()
    {
 
        // Display statement only
        System.out.println("Inside B, last() method");
    }
 
    // Method 2 of this class
    // Non-synchronized the method d2
    public void d2(A a)
    {
 
        // Display message only
        System.out.println(
            "Thread2 start execution of d2() method");
 
        // Try block to check for exceptions
        try {
 
            // Putting the current thread to sleep for
            // certain time using sleep() method
            Thread.sleep(2000);
 
            // Catch block to handle the exceptions
        }
        catch (InterruptedException e) {
 
            // Display the exception on the console
            System.out.println(e);
        }
 
        // Display message only
        System.out.println(
            "Thread2  trying to call A's last method");
 
        // Again calling the last() method inside this class
        a.last();
    }
}
 
// Class 3
// Main class
// Deadlock class which is extending Thread class
class GFG extends Thread {
 
    // Creating object of type class A
    A a = new A();
 
    // Creating object of type class B
    B b = new B();
 
    // Method 1
    public void m1()
    {
 
        // Starting the thread
        this.start();
 
        // Calling d1 method of class A
        a.d1(b);
    }
 
    // Method 2
    // run() method for the thread
    public void run()
    {
 
        // Calling d2 method of class B
        b.d2(a);
    }
 
    // Method 3
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating object of this class
        GFG deadlock = new GFG();
 
        // Calling m1 method
        deadlock.m1();
    }
}

 Producción:

Publicación traducida automáticamente

Artículo escrito por mroshanmishra0072 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *