分析java dump檔案
注意,請不要被我誤導,我沒有看其他資料,這是我自己分析的,有些可能是不對的
"DestroyJavaVM" prio=6 tid=0x00316800 nid=0x448 waiting on condition [0x00000000 ..0x00a0fd4c] java.lang.Thread.State: RUNNABLE "Thread-1" prio=6 tid=0x02f85000 nid=0xd18 waiting for monitor entry [0x0319f000 ..0x0319fd14] java.lang.Thread.State: BLOCKED (on object monitor) at xunlei.kkk.f2(TestLock.java - waiting to lock <0x22ad0160> (a java.lang.Object)//在“入口區”等待獲取<0x22ad0160> - locked <0x22ad0158> (a java.lang.Object)//獲得了監視器<0x22ad0158> at xunlei.TestLock$2.run(TestLock.java:42) "Thread-0" prio=6 tid=0x02bff400 nid=0xd40 waiting for monitor entry [0x02f4f000 ..0x02f4fd94] java.lang.Thread.State: BLOCKED (on object monitor) at xunlei.kkk.f1(TestLock.java:9) - waiting to lock <0x22ad0158> (a java.lang.Object) 在“入口區”等待獲取<0x22ad0158> - locked <0x22ad0160> (a java.lang.Object) //獲得了監視器<0x22ad0160> at xunlei.TestLock$1.run(TestLock.java |
"A2" prio=6 tid=0x02c01400 nid=0xb0c in Object.wait() [0x02fef000..0x02fefa94] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x22a15d48> (a java.lang.Object)//在“等待區”等待獲取<0x22a15d48> at java.lang.Object.wait(Object.java:485) at xunlei.OutputName.run(Test.java:58) - locked <0x22a15d48> (a java.lang.Object) "A1" prio=6 tid=0x02c00000 nid=0xf8 in Object.wait() [0x02f9f000..0x02f9fb14] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x22a15d48> (a java.lang.Object) at java.lang.Object.wait(Object.java:485) at xunlei.OutputName.run(Test.java:58) - locked <0x22a15d48> (a java.lang.Object) "A0" prio=6 tid=0x02c17800 nid=0xe68 in Object.wait() [0x02f4f000..0x02f4fb94] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x22a15d48> (a java.lang.Object) at java.lang.Object.wait(Object.java:485) at xunlei.OutputName.run(Test.java:58) - locked <0x22a15d48> (a java.lang.Object) |
在windows的cmd.exe中執行的java程式,按下ctrl+break,則會彈出此時程式的堆疊,上面顯示了執行緒的幾種狀態
一、- locked <0x22ad0158> (a java.lang.Object)
執行緒獲得了監視器<0x22ad0158>
二、- waiting to lock <0x22ad0160> (a java.lang.Object)
此執行緒不持有監視器<0x22ad0160>,但是它期待著獲得監視器<0x22ad0160>
此執行緒是在“入口區”等待獲取監視器<0x22ad0160>,即此執行緒不必等待其他執行緒執行<0x22ad0160>.notify()或<0x22ad0160>.notifyAll(),而是一旦<0x22ad0160>被其他執行緒釋放掉(通過其他執行緒<0x22ad0160>.notify()或<0x22ad0160>.notifyAll(),或者其他執行緒<0x22ad0160>.wait()),此執行緒總是會去爭搶<0x22ad0160>
三、- waiting on <0x22a15d48> (a java.lang.Object)
此執行緒剛剛執行了<0x22a15d48>.wait()後釋放了監視器<0x22a15d48>,並期望再次獲得<0x22a15d48>
此執行緒是在“等待區”等待獲取監視器<0x22a15d48>,當然,再次獲得時,需要其他執行緒呼叫<0x22a15d48>.notify()或<0x22a15d48>.notifyAll(),如果其他執行緒不呼叫<0x22a15d48>.notify()或<0x22a15d48>.notifyAll(),則此執行緒永遠不會復活
在下面的語句中
synchronized(obj) {// waiting to lock <0x22a15d48>
while(!condition) {
obj.wait();//waiting on <0x22a15d48>(不再持有監視器了,在“等待區”期待著再次獲得監視器)
}
// do when condition is OK
}
四、obj.wait()包含了兩層含義:
1、 此執行緒釋放了obj的監視器,即此執行緒現在已經不再持有obj的監視器啦
2、 在“等待區”等待著再次獲取obj的監視器(其他執行緒必須呼叫obj.notify()或obj.notifyAll(),如果僅僅執行完成synchronized語句或synchronized塊而沒有呼叫obj.notify()或obj.notifyAll(),則“等待區”中的執行緒就永遠不會甦醒)
五、執行緒的狀態
1、 java.lang.Thread.State: RUNNABLE,此執行緒正在執行
2、 java.lang.Thread.State: WAITING,此執行緒位於“等待區”,等待其他執行緒呼叫<0x22a15d48>.notifyAll(),否則,這個執行緒永遠不可能甦醒
3、 java.lang.Thread.State: BLOCKED,此執行緒位於“入口區”,且被阻塞了,在上面的例子中,死鎖了,永遠不會有解除block的機會(當然,在Java中,有些I/O方法也會阻塞的,不過,等到I/O完成後,就會自動解除block啦)