logo

Una situazione di stallo in Java

Deadlock in Java fa parte del multithreading. Il deadlock può verificarsi in una situazione in cui un thread è in attesa di un blocco dell'oggetto, acquisito da un altro thread e il secondo thread è in attesa di un blocco dell'oggetto acquisito dal primo thread. Poiché entrambi i thread attendono l'uno il rilascio del blocco dall'altro, la condizione viene chiamata deadlock.

Una situazione di stallo in Java

Esempio di Deadlock in Java

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

Produzione:

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

Deadlock più complicati

Un deadlock può includere anche più di due thread. Il motivo è che può essere difficile individuare una situazione di stallo. Ecco un esempio in cui quattro thread si sono bloccati:

Il thread 1 blocca A, attende B

Il thread 2 blocca B, attende C

Il thread 3 blocca C, attende D

Il thread 4 blocca D, attende A

Il thread 1 attende il thread 2, il thread 2 attende il thread 3, il thread 3 attende il thread 4 e il thread 4 attende il thread 1.

Come evitare lo stallo?

La soluzione ad un problema si trova alla radice. In una situazione di stallo, il problema principale è il modello di accesso alle risorse A e B. Per risolvere il problema dovremo semplicemente riordinare le istruzioni in cui il codice accede alle risorse condivise.

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

Produzione:

 In block 1 In block 2 

Nel codice precedente, la classe DeadlockSolved risolve il tipo di situazione di stallo. Aiuterà a evitare situazioni di stallo e, se incontrate, a risolverle.

Come evitare lo stallo in Java?

Le situazioni di stallo non possono essere completamente risolte. Ma possiamo evitarli seguendo le regole di base menzionate di seguito:

    Evita i blocchi nidificati: Dobbiamo evitare di dare blocchi a più thread, questo è il motivo principale di una condizione di deadlock. Normalmente accade quando si assegnano blocchi a più thread.Evita serrature non necessarie: I lucchetti dovrebbero essere dati ai fili importanti. Fornire blocchi ai thread non necessari che causano la condizione di deadlock.Utilizzo dell'unione di thread: Di solito si verifica un deadlock quando un thread attende il completamento dell'altro. In questo caso, possiamo usare giuntura con un tempo massimo impiegato da un thread.