Deadlock en Java fait partie du multithreading. Un blocage peut se produire dans une situation où un thread attend un verrou d'objet acquis par un autre thread et où le deuxième thread attend un verrou d'objet acquis par le premier thread. Étant donné que les deux threads attendent l’un l’autre pour libérer le verrou, la condition est appelée blocage.
Exemple de blocage 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(); } }
Sortir:
Thread 1: locked resource 1 Thread 2: locked resource 2
Des impasses plus compliquées
Un blocage peut également inclure plus de deux threads. La raison en est qu’il peut être difficile de détecter une impasse. Voici un exemple dans lequel quatre threads sont bloqués :
Le thread 1 verrouille A, attend B
Le thread 2 verrouille B, attend C
Le thread 3 verrouille C, attend D
ordre lexicographique
Le thread 4 verrouille D, attend A
répertoire de liste du système d'exploitation python
Le thread 1 attend le thread 2, le thread 2 attend le thread 3, le thread 3 attend le thread 4 et le thread 4 attend le thread 1.
Comment éviter une impasse ?
La solution à un problème se trouve à la racine. En cas d’impasse, c’est le modèle d’accès aux ressources A et B qui constitue le principal problème. Pour résoudre le problème, nous devrons simplement réorganiser les instructions dans lesquelles le code accède aux ressources partagées.
DeadlockRésolu.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; } } }
Sortir:
In block 1 In block 2
Dans le code ci-dessus, la classe DeadlockSolved résout le type de situation de blocage. Cela aidera à éviter les impasses et, le cas échéant, à les résoudre.
Comment éviter les blocages en Java ?
Les impasses ne peuvent pas être complètement résolues. Mais nous pouvons les éviter en suivant les règles de base mentionnées ci-dessous :