2010-11-13 78 views
6

正常情况下,当我要求线程转储时,很容易解释系统性能不佳的症状;即通常我能够看到许多线程显然正在等待已经获取但未被另一个人释放的监视器上。Java线程正在等待锁定不是(明显)锁定的对象

在这种情况下,我有很多线程正在等待显示器(0x965ad100),但没有一个显示器首先显示该显示器。有问题的线程可以用这个签名来识别:

等待锁定< 0x965ad100>(一uk.gov.dti.og.fox.ConAgent)

我试着用搜索引擎这一点,而我似乎发现的所有内容都是讨论锁定的显示器的帖子,没有关于等待未锁定的显示器的内容。

线程转储全部:http://www.basson.at/docs/stackoverflow/thread_dump.txt

我希望这里有人能解释我所看到的,或者至少指向我在正确的方向。预先感谢您的回复。

+0

BTW向下箭头访问启用它,你最好先检查一下什么是线程9这样做,是因为它在等待它已经收购了相同的锁(0x96560c48) – 2010-11-13 22:46:04

回答

1

当你的线程转储被执行时,线程刚刚释放监视器是可能的(尽管不太可能)。从监视器被释放到下一个线程获取它之间可能会有一段短暂的时间。如果你没有陷入真正的僵局,这可以解释你所看到的。尝试另一个线程转储并检查一个。

更可能的是,有一个线程已经存在的地方,已经拥有显示器。有时不明显。你的堆栈跟踪有一些“锁定”行,列出了持有某些锁的线程,但该列表不一定是完整的。例如,我怀疑通过JNI获得的锁没有列出。

如果您可以用内置锁来替换, java.util.concurrent.locks.ReentrantLock,那么你可以暂停程序并附加一个调试器,找到你关心的锁,然后使用getOwner方法找到锁拥有者。

1

如果您使用的是Eclipse,则可以通过Debug视图使用内置的锁定查看器,这可能会有帮助。您可以使用下拉菜单通过工具栏:)

alt text