如何检查哪个线程正在占用监视器?

How to check which thread is holding the monitor?

我遇到了性能问题(在使用并行集合和期货的复杂 Scala 代码中)。我已经使用 JFR 检查了更多细节,我可以看到问题本身表现为等待监视器对象的线程(线程似乎正在等待 java.util.concurrent.ForkJoinTask#internalWait 通过调用 wait 方法 ForkJoinTask).我想知道哪个线程持有这个监视器对象(以及从哪个函数/调用堆栈进入监视器)。 JFR 向我显示了监视器的某种地址,但我没有找到通过该地址搜索/过滤的方法。

JMC 中是否有一些视图、插件或其他方式如何检查谁以及何时锁定和释放给定的监视器?

问题是,正在等待的监视器对象在技术上不被任何线程持有。这样的监视器没有“所有者”。通常,您无法事先知道哪个线程负责调用 notify,因为它可以是任何线程,也可以根本没有线程。

但是,如果监视器已经被通知,将有一个JFR 事件包含有关通知程序线程的信息。您可以在屏幕截图中看到它:scala-execution-context-global-54 线程通知监视器。