默认情况下,使用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)如果没有这个选项,就不可能在事后判断哪个线程持有这个锁。为什么此选项不是默认选项?是否存在一些不明显的性能或稳定性损失?当我寻找关于这一点的讨论时,什么也没有出现。
发布于 2011-09-02 02:40:20
我询问了Oracle (我的雇主有一个支持联系人),答案基本上是该选项可以安全使用,而且许多纯诊断功能在默认情况下是禁用的,这就是这些选项之一。如果诊断功能是安全和稳定的,并且不会带来性能损失,那么它应该在默认情况下处于打开状态。这似乎不是(当时) Sun和(现在) Oracle的视图。
发布于 2011-08-16 13:04:13
好吧,我的猜测是它是不稳定的,或者JVM维护者(Sun-now-Oracle)根本不想把它作为一个受支持的特性来维护。只需通过-XX:前缀就可以看出这一点:
使用-XX指定的
选项不稳定,不建议随意使用。这些选项如有更改,恕不另行通知。
-来自
另外,在该页面中,可以通过JDK管理接口动态启用或禁用该选项,因此如果需要,可以通过MXBean启用它。
标记为可管理的
标志可以通过com.sun.management.HotSpotDiagnosticMXBean管理接口( JDK )和JConsole动态写入。在监视和管理Java SE 6平台应用程序中,图3显示了一个示例。可管理标志也可以通过jinfo -flag设置。
最后,jstack堆栈跟踪工具可以随时执行相同的功能,而无需始终启用它。
发布于 2017-09-08 06:57:45
因为只有ReentrantLocks知道它们与哪些线程相关。要在运行时获取此信息,此方法的实现应遍历堆以查找所有锁及其线程。
https://stackoverflow.com/questions/7071643
复制相似问题