Java'daki kilitlenme, çoklu iş parçacığının bir parçasıdır. Bir iş parçacığının başka bir iş parçacığı tarafından elde edilen bir nesne kilidini beklediği ve ikinci iş parçacığının birinci iş parçacığı tarafından elde edilen bir nesne kilidini beklediği bir durumda kilitlenme meydana gelebilir. Her iki thread de birbirinin kilidi açmasını beklediği için bu duruma deadlock denir.
Java'da Kilitlenme Örneği
TestDeadlockÖrnek1.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(); } }
Çıktı:
Thread 1: locked resource 1 Thread 2: locked resource 2
Daha Karmaşık Kilitlenmeler
Bir kilitlenme ayrıca ikiden fazla iş parçacığı içerebilir. Bunun nedeni, bir kilitlenmeyi tespit etmenin zor olabilmesidir. İşte dört iş parçacığının kilitlendiği bir örnek:
Konu 1 A'yı kilitler, B'yi bekler
Konu 2 B'yi kilitler, C'yi bekler
Konu 3, C'yi kilitler, D'yi bekler
Konu 4, D'yi kilitler, A'yı bekler
İş parçacığı 1 iş parçacığı 2'yi bekler, iş parçacığı 2 iş parçacığı 3'ü bekler, iş parçacığı 3 iş parçacığı 4'ü bekler ve iş parçacığı 4 iş parçacığı 1'i bekler.
Kilitlenme nasıl önlenir?
Sorunun çözümü kökünde bulunur. Kilitlenmede asıl konu A ve B kaynaklarına erişim şeklidir. Sorunu çözmek için kodun paylaşılan kaynaklara eriştiği ifadeleri yeniden sıralamamız gerekecek.
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; } } }
Çıktı:
In block 1 In block 2
Yukarıdaki kodda DeadlockSolved sınıfı, kilitlenme türünü çözer. Kilitlenmelerden kaçınmaya ve karşılaşıldığında bunların çözülmesine yardımcı olacaktır.
Java'da Kilitlenmeden Nasıl Kaçınılır?
Kilitlenmeler tamamen çözülemez. Ancak aşağıda belirtilen temel kuralları izleyerek bunlardan kaçınabiliriz: