Strupceļš Java ir daļa no daudzpavedienu izveides. Strupceļš var rasties situācijā, kad pavediens gaida objekta bloķēšanu, ko iegūst cits pavediens, un otrais pavediens gaida objekta bloķēšanu, ko iegūst pirmais pavediens. Tā kā abi pavedieni gaida, kamēr viens otrs atbrīvos slēdzeni, stāvokli sauc par strupceļu.
Strupceļa piemērs 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(); } }
Izvade:
Thread 1: locked resource 1 Thread 2: locked resource 2
Sarežģītāki strupceļi
Strupceļā var būt arī vairāk nekā divi pavedieni. Iemesls ir tāds, ka var būt grūti noteikt strupceļu. Šeit ir piemērs, kurā četri pavedieni ir nonākuši strupceļā:
1. vītne nofiksē A, gaida B
Pavediet 2 slēdzenes B, gaidiet C
Vītne 3 slēdzenes C, gaida D
Vītne 4 slēdzenes D, gaida A
1. pavediens gaida 2. vītni, 2. vītne gaida 3. vītni, 3. vītne gaida 4. vītni un 4. vītne gaida 1. vītni.
Kā izvairīties no strupceļa?
Problēmas risinājums ir atrodams tās saknēs. Strupceļā galvenā problēma ir pieeja A un B resursiem. Lai atrisinātu problēmu, mums būs vienkārši jāpārkārto priekšraksti, kuros kods piekļūst koplietotajiem resursiem.
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; } } }
Izvade:
In block 1 In block 2
Iepriekš minētajā kodā klase DeadlockSolved atrisina strupceļa veida situāciju. Tas palīdzēs izvairīties no strupceļiem un, ja rodas, tos atrisināt.
Kā izvairīties no strupceļa Java?
Strupceļus nevar pilnībā novērst. Bet mēs varam no tiem izvairīties, ievērojot tālāk minētos pamatnoteikumus: