2011-10-05 91 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()。 –