logo

Java'da kilitlenme

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

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:

    İç İçe Kilitlerden Kaçının: Birden fazla thread'e kilit vermekten kaçınmalıyız, deadlock durumunun ana nedeni budur. Normalde birden fazla iş parçacığına kilit verdiğinizde olur.Gereksiz Kilitlerden Kaçının: Önemli konulara kilit verilmelidir. Deadlock durumuna neden olan gereksiz threadlere kilit verilmesi.Konu Birleştirmeyi Kullanma: Kilitlenme genellikle bir iş parçacığının diğerinin bitmesini beklemesi durumunda meydana gelir. Bu durumda şunu kullanabiliriz: katılmak bir iş parçacığının alacağı maksimum süre ile.