注意,請不要被我誤導,我沒有看其他資料,這是我自己分析的,有些可能是不對的
-
"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:20)
- 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:35)
"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啦)