2011-10-05 95 views
14

我正在繼續深入理解Java線程的途徑。不幸的是,我的Java認證並未涵蓋該部分,因此學習的唯一方法是發佈一系列愚蠢的問題。有了這麼多年的Java開發,我有時想知道我還有多少東西需要學習:-)瞭解引用處理程序線程

特別是我現在關注引用處理程序線程。

"Reference Handler" daemon prio=10 tid=0x02da3400 nid=0xb98 in Object.wait() [0x0302f000] 
    java.lang.Thread.State: WAITING (on object monitor) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x1aac0320> (a java.lang.ref.Reference$Lock) 
    at java.lang.Object.wait(Object.java:485) 
    at java.lang.ref.Reference$ReferenceHandler.run(Unknown Source) 
    - locked <0x1aac0320> (a java.lang.ref.Reference$Lock) 

現在的一些問題是下面的,對一些人我知道答案,但我不張貼,因爲我想聽聽別人的意見:

  1. 什麼是指向處理器線程應該這樣做?
  2. 線程轉儲應該被視爲自下而上,爲什麼堆棧跟蹤以鎖定開始,至少在線程運行後不​​應該出現鎖定語句?
  3. 「本地方法」是指什麼?
  4. 爲什麼「未知源」,在這種情況下,線程轉儲無法調用源代碼?
  5. 最後等待和鎖定有相同的,爲什麼?

像往常一樣,我懇請回答所有問題,以便我可以標記回答。

回答

11
  1. 嫌疑它處理運行的JVM終結。這是一個實現細節,因此未在JVM規範中指定。
  2. 這僅意味着該java.lang.ref.Reference$Lock被鎖定在線路前述它(即,在ReferenceHandler.run()
  3. 「天然方法」只是意味着,該方法在天然實現(即非Java)代碼中提到的方法(想想JNI)
  4. 未知來源僅意味着.class文件不包含任何源代碼位置信息(至少對於此特定點)。如果該方法是合成的,則可能發生(doesn'在這裏看起來像這樣),或者這個類沒有調試信息編譯。
  5. 當一個線程等待一些對象上,那麼它必須鎖定該對象在某些時候下來呼叫跟蹤,所以你無法真的有waiting on沒有相應的locked
+0

呃...關於第5點,它是有道理的,我們可以說,當一個'等待'的聲明出現,然後在堆棧跟蹤一個'鎖'具有相同的地址總是出現? – Leonardo

+0

好吧,如果你可以解釋更多關於問題1,我可以標記整體解決:-) – Leonardo

2

哇,對我來說太深了。我只能回答你的一個或兩個問題。

「本地方法」僅僅意味着該方法的實現在某些本地(即C或C++)庫中。一旦調用堆棧「變得原生」,JVM就不能再監視它了。沒辦法提供額外的堆棧信息。

「未知來源」可能意味着代碼是在優化打開並關閉調試信息的情況下編譯的(-g標誌?)。這消除了.class文件中的文件/行信息。

+0

3和4回答得好,不幸的是我需要所有這些標記爲回答。 – Leonardo

3

1)終結器線程調用終結器方法。 參考線程有類似的目的。

http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Core/lang/java/lang/ref/Reference.java.htm

在OpenJDK源指出它是一個

高優先級的線程來排隊待審參考

的GC產生哪些需要處理引用的一個簡單的鏈表並且這個線程很快將它們添加到適當的隊列中。這是分兩個階段完成的原因是GC沒有做任何事情,只能找到引用,這個線程調用處理這些引用的代碼。調用清除程序,並通知ReferenceQueue偵聽器。

2)在輸入之前獲取同步方法的鎖定。

3-5)由約阿希姆覆蓋;)

+0

謝謝,這完全覆蓋問題一。 – Leonardo

+0

太好了。你能否解釋未決引用的含義? – user12458

+0

@JavaTechnical這些引用的對象需要在它們在下一個GC上清理之前調用它們的finalize()。 –