logo

Zastoj v Javi

Zastoj v Javi je del večnitnosti. Do zastoja lahko pride v primeru, ko nit čaka na zaklepanje objekta, ki ga pridobi druga nit, druga nit pa čaka na zaklepanje objekta, ki ga pridobi prva nit. Ker obe niti čakata druga na drugo, da sprostita zaklepanje, se stanje imenuje zastoj.

Zastoj v Javi

Primer zastoja v Javi

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

Izhod:

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

Bolj zapleteni zastoji

Zastoj lahko vključuje tudi več kot dve niti. Razlog je v tem, da je težko odkriti zastoj. Tukaj je primer, v katerem so štiri niti zastale:

Nit 1 zaklene A, čaka na B

Nit 2 zaklene B, čaka na C

Niti 3 ključavnice C, čaka na D

Nit 4 zaklene D, čaka na A

Nit 1 čaka na nit 2, nit 2 čaka na nit 3, nit 3 čaka na nit 4 in nit 4 čaka na nit 1.

Kako se izogniti zastoju?

Rešitev za problem se najde v njegovih koreninah. V zastoju je glavni problem vzorec dostopa do virov A in B. Da bi rešili težavo, bomo morali preprosto preurediti stavke, kjer koda dostopa do skupnih virov.

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

Izhod:

 In block 1 In block 2 

V zgornji kodi razred DeadlockSolved rešuje vrsto situacije zastoja. Pomagal bo pri izogibanju zastojem in, če do njih pride, pri njihovem reševanju.

Kako se izogniti zastoju v Javi?

Zastojev ni mogoče popolnoma rešiti. Lahko pa se jim izognemo, če upoštevamo spodaj navedena osnovna pravila:

    Izogibajte se ugnezdenim ključavnicam: Izogibati se moramo zaklepanju več niti, to je glavni razlog za stanje zastoja. Običajno se zgodi, ko zaklenete več niti.Izogibajte se nepotrebnim zaklepanjem: Ključavnice je treba nameniti pomembnim nitim. Zaklepanje nepotrebnih niti, ki povzročajo stanje zastoja.Uporaba Thread Join: Zastoj se običajno zgodi, ko ena nit čaka, da druga konča. V tem primeru lahko uporabimo pridruži se z največjim časom, ki ga bo vzela nit.