El bloqueig a Java és una part del multithreading. El bloqueig es pot produir en una situació en què un fil està esperant un bloqueig d'objecte, que és adquirit per un altre fil i el segon fil està esperant un bloqueig d'objecte que és adquirit pel primer fil. Atès que ambdós fils estan esperant l'un a l'altre per alliberar el bloqueig, la condició s'anomena bloqueig.
Exemple de Deadlock a 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(); } }
Sortida:
Thread 1: locked resource 1 Thread 2: locked resource 2
Bloquejos més complicats
Un bloqueig també pot incloure més de dos fils. El motiu és que pot ser difícil detectar un bloqueig. Aquí teniu un exemple en què quatre fils s'han bloquejat:
El fil 1 bloqueja A, espera B
El fil 2 bloqueja B, espera C
El fil 3 bloqueja C, espera D
El fil 4 bloqueja D, espera A
El fil 1 espera el fil 2, el fil 2 espera el fil 3, el fil 3 espera el fil 4 i el fil 4 espera el fil 1.
Com evitar el bloqueig?
La solució a un problema es troba a les seves arrels. En punt mort és el patró d'accés als recursos A i B, és el tema principal. Per resoldre el problema haurem de reordenar simplement les declaracions on el codi accedeix als recursos compartits.
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; } } }
Sortida:
In block 1 In block 2
Al codi anterior, la classe DeadlockSolved resol el tipus de situació de bloqueig. Ajudarà a evitar bloquejos i, si es troba, a resoldre'ls.
Com evitar el bloqueig a Java?
Els bloquejos no es poden resoldre completament. Però podem evitar-los seguint les regles bàsiques esmentades a continuació: