logo

Zablokování v Javě

Deadlock v Javě je součástí multithreadingu. Zablokování může nastat v situaci, kdy vlákno čeká na zámek objektu, který je získán jiným vláknem, a druhé vlákno čeká na zámek objektu, který je získán prvním vláknem. Protože obě vlákna na sebe čekají, až uvolní zámek, stav se nazývá uváznutí.

Zablokování v Javě

Příklad Deadlock v Javě

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

Výstup:

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

Složitější zablokování

Zablokování může také zahrnovat více než dvě vlákna. Důvodem je, že může být obtížné odhalit uváznutí. Zde je příklad, kdy došlo k uváznutí čtyř vláken:

import skeneru java

Vlákno 1 zamyká A, čeká na B

Závit 2 zámky B, čeká na C

Závit 3 zámky C, čeká na D

Závit 4 zámky D, čeká na A

uml diagram java

Vlákno 1 čeká na vlákno 2, vlákno 2 čeká na vlákno 3, vlákno 3 čeká na vlákno 4 a vlákno 4 čeká na vlákno 1.

algoritmus pro bfs

Jak se vyhnout patové situaci?

Řešení problému se nachází v jeho kořenech. V uváznutí je hlavním problémem způsob přístupu ke zdrojům A a B. Abychom problém vyřešili, budeme muset jednoduše přeuspořádat příkazy, kde kód přistupuje ke sdíleným zdrojům.

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

Výstup:

 In block 1 In block 2 

Ve výše uvedeném kódu řeší třída DeadlockSolved situaci typu uváznutí. Pomůže to vyhnout se patovým situacím, a pokud na ně narazí, tak je vyřešit.

Jak se vyhnout zablokování v Javě?

Zablokování nelze zcela vyřešit. Můžeme se jim však vyhnout dodržováním základních pravidel uvedených níže:

    Vyhněte se vnořeným zámkům: Musíme se vyvarovat zamykání více vláken, to je hlavní důvod stavu uváznutí. Obvykle se to stane, když zamknete více vláken.Vyhněte se zbytečným zámkům: Zámky by měly být přiděleny důležitým vláknům. Udělování zámků nepotřebným vláknům, která způsobují zablokování.Použití Thread Join: Zablokování obvykle nastane, když jedno vlákno čeká na dokončení druhého. V tomto případě můžeme použít připojit s maximální dobou, kterou vlákno zabere.