Java Language Création d'un système bloqué de base


Exemple

Une impasse se produit lorsque deux actions concurrentes attendent que l'autre se termine et que, par conséquent, aucune de ces actions ne se produit jamais. En Java, un verrou est associé à chaque objet. Pour éviter les modifications simultanées effectuées par plusieurs threads sur un seul objet, nous pouvons utiliser synchronized mot clé synchronized , mais tout est payant. L'utilisation incorrecte de mots clés synchronized peut conduire à des systèmes bloqués appelés systèmes bloqués.

Considérons qu'il y a 2 threads travaillant sur 1 instance, Lets appelle les threads comme First et Second, et disons que nous avons 2 ressources R1 et R2. First acquiert R1 et a également besoin de R2 pour son achèvement tandis que Second acquiert R2 et a besoin de R1 pour son achèvement.

donc à l'instant t = 0,

Le premier a R1 et le second a R2. maintenant First attend R2 alors que Second attend R1. cette attente est indéfinie et cela conduit à une impasse.

public class Example2 {
    
    public static void main(String[] args) throws InterruptedException {
        final DeadLock dl = new DeadLock();
        Thread t1 = new Thread(new Runnable() {
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                dl.methodA();
            }
        });
   
        Thread t2 = new Thread(new Runnable() {
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    dl.method2();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        t1.setName("First");
        t2.setName("Second");
        t1.start();
        t2.start();
    }
}

class DeadLock {
    
    Object mLock1 = new Object();
    Object mLock2 = new Object();
    

    public void methodA() {
        System.out.println("methodA wait for mLock1  " + Thread.currentThread().getName());
        synchronized (mLock1) {
            System.out.println("methodA mLock1 acquired   " + Thread.currentThread().getName());
            try {
                Thread.sleep(100);
                method2();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public void method2() throws InterruptedException {
        System.out.println("method2 wait for mLock2  " + Thread.currentThread().getName());
        synchronized (mLock2) {
            System.out.println("method2  mLock2 acquired   " + Thread.currentThread().getName());
            Thread.sleep(100);
            method3();
        }
    }
    public void method3() throws InterruptedException {
        System.out.println("method3  mLock1  "+ Thread.currentThread().getName());
        synchronized (mLock1) {
            System.out.println("method3   mLock1 acquired  " + Thread.currentThread().getName());
        }
    }
}

Sortie de ce programme:

methodA wait for mLock1  First
method2 wait for mLock2  Second
method2  mLock2 acquired   Second
methodA mLock1 acquired   First
method3  mLock1  Second
method2 wait for mLock2  First