默认情况下,使用Hotspot,CTRL-Break线程转储不会列出哪些线程持有java.lang.concurrent
锁。我理解,使用这些锁,Hotspot无法获得有关获取锁的堆栈帧的信息。如果添加JVM选项-XX:+PrintConcurrentLocks
,则CTRL-Break堆栈转储将列出(在线程的堆栈跟踪之后)该帧持有的任何并发锁定。例如:
"D-Java-5-Lock" prio=6 tid=0x00000000069a1800 nid=0x196c runnable [0x000000000770f000]
java.lang.Thread.State: RUNNABLE
at com.Tester.longDelay(Tester.java:41)
at com.Tester$D.run(Tester.java:88)
Locked ownable synchronizers:
- <0x00000007d6030898> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
如果没有此选项,则无法确定验尸中持有此锁的线程。为什么此选项不是默认选项?是否存在一些不明显的性能或稳定性惩罚?当我寻找对此的讨论时,什么都没有出现。
答案 0 :(得分:2)
嗯,我的猜测是它不稳定,或者JVM维护者(Sun-now-Oracle)根本不想将其维护为受支持的功能。您只需通过-XX:
前缀:
使用-XX指定的选项不稳定,不建议用于临时使用。这些选项如有更改,恕不另行通知。
同样从该页面,可以通过JDK管理界面动态启用或禁用该选项,因此您可以根据需要通过MXBean启用它。
标记为可管理的标志可通过JDK管理界面(com.sun.management.HotSpotDiagnosticMXBean API)和JConsole动态写入。在监视和管理Java SE 6平台应用程序中,图3显示了一个示例。可管理标志也可以通过jinfo -flag设置。
最后,jstack堆栈跟踪工具可以随时执行相同的功能,而无需一直启用它。
答案 1 :(得分:2)
我问过Oracle(我的雇主有一个支持联系人),答案基本上是该选项可以安全使用,并且默认情况下禁用了许多纯诊断功能,这是其中一个选项。 IMO,如果诊断功能安全稳定且不会引入性能损失,则默认情况下应该启用它。看起来这不是(当时)Sun和(现在)Oracle的观点。
答案 2 :(得分:1)
因为,只有ReentrantLocks知道它们与哪些线程相关。要获取有关此方法的运行时实现的此信息,请通过堆查找所有锁及其线程。