logo

Безизходица в Java

Deadlock в Java е част от многопоточността. Застой може да възникне в ситуация, когато нишка чака заключване на обект, което е придобито от друга нишка, а втората нишка чака заключване на обект, което е придобито от първата нишка. Тъй като и двете нишки чакат една друга да освободят заключването, състоянието се нарича блокиране.

Безизходица в Java

Пример за Deadlock в 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(); } } 

Изход:

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

По-сложни блокировки

Блокирането може също да включва повече от две нишки. Причината е, че може да бъде трудно да се открие задънена улица. Ето пример, в който четири нишки са блокирали:

Нишка 1 заключва A, изчаква B

Нанижете 2 ключалки B, изчакайте C

Нанижете 3 кичура C, изчаква D

Резба 4 заключва D, изчаква A

Нишка 1 чака нишка 2, нишка 2 чака нишка 3, нишка 3 чака нишка 4 и нишка 4 чака нишка 1.

Как да избегнем задънена улица?

Решението на проблема се намира в корените му. В задънена улица моделът на достъп до ресурсите A и B е основният проблем. За да разрешим проблема, ще трябва просто да пренаредим изразите, където кодът има достъп до споделени ресурси.

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

Изход:

 In block 1 In block 2 

В кода по-горе класът DeadlockSolved разрешава ситуацията на задънена улица. Това ще помогне за избягване на безизходици и, ако възникнат, за разрешаването им.

Как да избегнете блокиране в Java?

Безизходиците не могат да бъдат напълно разрешени. Но можем да ги избегнем, като следваме основните правила, посочени по-долу:

    Избягвайте вложени ключалки: Трябва да избягваме да даваме ключалки на множество нишки, това е основната причина за състояние на блокиране. Обикновено се случва, когато дадете ключалки на множество нишки.Избягвайте ненужните ключалки: Бравите трябва да бъдат дадени на важните нишки. Предоставяне на ключалки на ненужните нишки, които причиняват състоянието на блокиране.Използване на Thread Join: Блокировка обикновено се случва, когато една нишка чака другата да завърши. В този случай можем да използваме присъединяване с максимално време, което една нишка ще отнеме.