Deadlock în Java face parte din multithreading. Blocarea poate apărea într-o situație în care un fir de execuție așteaptă o blocare a obiectului, care este dobândită de un alt fir de execuție, iar cel de-al doilea fir așteaptă o blocare a obiectului care este achiziționată de primul fir de execuție. Deoarece ambele fire se așteaptă unul pe celălalt să elibereze blocarea, condiția se numește deadlock.
Exemplu de blocaj în Java
TestDeadlockExample1.java
salvat de
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(); } }
Ieșire:
Thread 1: locked resource 1 Thread 2: locked resource 2
Blocaje mai complicate
Un blocaj poate include, de asemenea, mai mult de două fire. Motivul este că poate fi dificil să detectați un impas. Iată un exemplu în care patru fire au blocat:
Firul 1 blochează A, așteaptă B
Filetul 2 blochează B, așteaptă C
Firul 3 blochează C, așteaptă D
Firul 4 blochează D, așteaptă A
Firul 1 așteaptă firul 2, firul 2 așteaptă firul 3, firul 3 așteaptă firul 4 și firul 4 așteaptă firul 1.
.egal cu java
Cum să evitați blocajul?
O soluție pentru o problemă se găsește la rădăcini. În deadlock este modelul de accesare a resurselor A și B, este problema principală. Pentru a rezolva problema, va trebui să reordonăm pur și simplu instrucțiunile în care codul accesează resurse partajate.
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; } } }
Ieșire:
In block 1 In block 2
În codul de mai sus, clasa DeadlockSolved rezolvă situația de tip impas. Va ajuta la evitarea blocajelor și, dacă este întâlnit, la rezolvarea acestora.
Cum să eviți blocajul în Java?
Blocajele nu pot fi rezolvate complet. Dar le putem evita urmând regulile de bază menționate mai jos: