logo

Blocaj în Java

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.

Blocaj în Java

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:

    Evitați încuietorile imbricate: Trebuie să evităm să dăm blocări mai multor fire, acesta este principalul motiv pentru o condiție de blocaj. În mod normal, se întâmplă când dați blocări mai multor fire.Evitați încuietorile inutile: Încuietorile ar trebui să fie date firelor importante. Acordarea de blocări firelor inutile care provoacă starea de blocaj.Utilizarea Thread Join: De obicei, un blocaj are loc atunci când un fir așteaptă ca celălalt să se termine. În acest caz, putem folosi a te alatura cu un timp maxim pe care îl va lua un fir.