Java Kilitlenme Programlı Olarak Nasıl Oluşturulur ve Kilitlenme Nasıl Analiz Edilir
Yayınlanan: 2013-07-03Kilitlenme, iki veya daha fazla iş parçacığının sonsuza kadar engellendiği bir programlama durumudur, bu durum en az iki iş parçacığı ve iki veya daha fazla kaynak ile ortaya çıkar.
Burada kilitlenme senaryosuna neden olacak basit bir program yazdım ve sonra nasıl analiz edileceğini göreceğiz.
İşte basit bir Java Örneği:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
package com . crunchify . tutorials ; import java . lang . management . ManagementFactory ; import java . lang . management . ThreadInfo ; import java . lang . management . ThreadMXBean ; /** * @author Crunchify.com * */ public class CrunchifyThreadDeadLock { public static void main ( String [ ] args ) throws InterruptedException { Object obj1 = new Object ( ) ; Object obj2 = new Object ( ) ; Object obj3 = new Object ( ) ; Thread crunchifyThread1 = new Thread ( new CrunchifySynchronizeThread ( obj1 , obj2 ) , "crunchifyThread1" ) ; Thread crunchifyThread2 = new Thread ( new CrunchifySynchronizeThread ( obj2 , obj3 ) , "crunchifyThread2" ) ; Thread crunchifyThread3 = new Thread ( new CrunchifySynchronizeThread ( obj3 , obj1 ) , "crunchifyThread3" ) ; crunchifyThread1 . start ( ) ; Thread . sleep ( 3000 ) ; crunchifyThread2 . start ( ) ; Thread . sleep ( 3000 ) ; crunchifyThread3 . start ( ) ; } } class CrunchifySynchronizeThread implements Runnable { private Object obj1 ; private Object obj2 ; public CrunchifySynchronizeThread ( Object obj1 , Object obj2 ) { this . obj1 = obj1 ; this . obj2 = obj2 ; } @Override public void run ( ) { String name = Thread . currentThread ( ) . getName ( ) ; synchronized ( obj1 ) { System . out . println ( name + " acquired lock on Object1: " + obj1 ) ; try { Thread . sleep ( 10000 ) ; } catch ( InterruptedException e ) { e . printStackTrace ( ) ; } synchronized ( obj2 ) { System . out . println ( name + " acquired lock on Object2: " + obj2 ) ; } System . out . println ( name + " released lock on Object2: " + obj2 ) ; } System . out . println ( name + " released lock on Object1: " + obj1 ) ; System . out . println ( name + " Finished Crunchify Deadlock Test." ) ; } } |
Çıktı:

1 2 3 |
crunchifyThread1 acquired lock on Object1 : java . lang . Object @ 59e3bddb crunchifyThread2 acquired lock on Object1 : java . lang . Object @ 294e430c crunchifyThread3 acquired lock on Object1 : java . lang . Object @ 246972f1 |
Uygulamanız yukarıdaki örnekte olduğu gibi asılıyken, bir thread dökümü alabilir ve kilitlenen konuları görebilirsiniz.
Örneğin, Mac'te, kilitlenmenin nerede olduğunu çok açık hale getiren iş parçacığı dökümünü almak için Ctrl-\
yapabilir veya jstack
ve işlem kimliğini kullanabilirsiniz.
Bu örnekte, iş parçacığı dökümü şöyle görünür:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
"crunchifyThread3" java . lang . Thread . State : RUNNABLE at sun . management . ThreadImpl . getThreadInfo1 ( Native Method ) at sun . management . ThreadImpl . getThreadInfo ( ThreadImpl . java : 174 ) at com . crunchify . tutorials . CrunchifySynchronizeThread . getThreadDump ( CrunchifyThreadDeadLock . java : 64 ) at com . crunchify . tutorials . CrunchifySynchronizeThread . run ( CrunchifyThreadDeadLock . java : 50 ) at java . lang . Thread . run ( Thread . java : 722 ) "crunchifyThread2" java . lang . Thread . State : BLOCKED at com . crunchify . tutorials . CrunchifySynchronizeThread . run ( CrunchifyThreadDeadLock . java : 53 ) at java . lang . Thread . run ( Thread . java : 722 ) "crunchifyThread1" java . lang . Thread . State : BLOCKED at com . crunchify . tutorials . CrunchifySynchronizeThread . run ( CrunchifyThreadDeadLock . java : 53 ) at java . lang . Thread . run ( Thread . java : 722 ) "Signal Dispatcher" java . lang . Thread . State : RUNNABLE "Finalizer" java . lang . Thread . State : WAITING at java . lang . Object . wait ( Native Method ) at java . lang . ref . ReferenceQueue . remove ( ReferenceQueue . java : 135 ) at java . lang . ref . ReferenceQueue . remove ( ReferenceQueue . java : 151 ) at java . lang . ref . Finalizer $ FinalizerThread . run ( Finalizer . java : 189 ) "Reference Handler" java . lang . Thread . State : WAITING at java . lang . Object . wait ( Native Method ) at java . lang . Object . wait ( Object . java : 503 ) at java . lang . ref . Reference $ ReferenceHandler . run ( Reference . java : 133 ) |
Burada BLOCKED ve WAITING threads => Deadlock
durumu fark edildi.. Bir sonraki örnekte, programlı olarak yukarıdaki thread dökümünü oluşturmak için basit Java Programı sağlanacaktır.