logo

Deadlock in Java

Deadlock ist in Java ein Teil des Multithreadings. Ein Deadlock kann in einer Situation auftreten, in der ein Thread auf eine Objektsperre wartet, die von einem anderen Thread erworben wird, und ein zweiter Thread auf eine Objektsperre wartet, die vom ersten Thread erworben wird. Da beide Threads darauf warten, dass der andere die Sperre aufhebt, wird dieser Zustand als Deadlock bezeichnet.

Deadlock in Java

Beispiel für Deadlock in 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(); } } 

Ausgabe:

 Thread 1: locked resource 1 Thread 2: locked resource 2 

Kompliziertere Deadlocks

Ein Deadlock kann auch mehr als zwei Threads umfassen. Der Grund dafür ist, dass es schwierig sein kann, einen Deadlock zu erkennen. Hier ist ein Beispiel, in dem vier Threads blockiert sind:

Thread 1 sperrt A und wartet auf B

Thread 2 sperrt B und wartet auf C

Thread 3 sperrt C und wartet auf D

Thread 4 sperrt D und wartet auf A

Java liest CSV-Datei

Thread 1 wartet auf Thread 2, Thread 2 wartet auf Thread 3, Thread 3 wartet auf Thread 4 und Thread 4 wartet auf Thread 1.

Wie vermeide ich einen Deadlock?

Eine Lösung für ein Problem findet sich an der Wurzel. Bei einem Deadlock ist das Muster des Zugriffs auf die Ressourcen A und B das Hauptproblem. Um das Problem zu lösen, müssen wir einfach die Anweisungen neu anordnen, in denen der Code auf gemeinsam genutzte Ressourcen zugreift.

DeadlockSolved.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; } } } 

Ausgabe:

 In block 1 In block 2 

Im obigen Code löst die Klasse DeadlockSolved die Deadlock-Situation. Dies hilft dabei, Deadlocks zu vermeiden und, falls sie auftreten, diese zu beheben.

Wie vermeide ich Deadlocks in Java?

Deadlocks können nicht vollständig gelöst werden. Aber wir können sie vermeiden, indem wir die unten aufgeführten Grundregeln befolgen:

    Vermeiden Sie verschachtelte Sperren: Wir müssen vermeiden, mehreren Threads Sperren zu erteilen. Dies ist der Hauptgrund für einen Deadlock-Zustand. Dies geschieht normalerweise, wenn Sie mehrere Threads sperren.Vermeiden Sie unnötige Sperren: Die Sperren sollten an die wichtigen Threads vergeben werden. Sperren für unnötige Threads, die den Deadlock-Zustand verursachen.Verwenden von Thread Join: Ein Deadlock tritt normalerweise auf, wenn ein Thread darauf wartet, dass der andere beendet wird. In diesem Fall können wir verwenden verbinden mit einer maximalen Zeit, die ein Thread benötigt.