作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这类似于 Java thread dump: BLOCKED thread without "waiting to lock ..." .
基本上,我看到一个 BLOCKED 线程,但它有它正在等待的锁:
"pool-1-thread-60" prio=10 tid=0x00007fbf10017000 nid=0x210 waiting for monitor entry [0x00007fbed64e3000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.apache.log4j.Category.callAppenders(Category.java:204)
- locked <0x0000000742444ad0> (a org.apache.log4j.Logger)
at org.apache.log4j.Category.forcedLog(Category.java:391)
at org.apache.log4j.Category.info(Category.java:666)
...
我希望看到 - waiting to lock <0x0000000742444ad0>...
而不是 - locked...
.另一个问题表明垃圾收集是原因,但如果是这样,不是所有线程都被阻塞了吗?还有其他可运行的线程。另外,我怎么能证明是这样呢?为什么这是观察到的行为?我不想盲目地假设它是垃圾收集器,但几天后才发现它是别的东西。
==辅助信息==
虽然我认为它与手头的问题无关,但这是上述转储来自的代码部分。
for(Category c = this; c != null; c=c.parent) {
// Protected against simultaneous call to addAppender, removeAppender,...
synchronized(c) { //line 204
if(c.aai != null) {
writes += c.aai.appendLoopOnAppenders(event);
}
if(!c.additive) {
break;
}
}
}
很明显,该行需要获取一个锁。然而,当一个线程在这个监视器上真正被阻塞时,线程转储中的输出看起来像(这来自同一个转储):
"pool-1-thread-44" prio=10 tid=0x00007fbef0051000 nid=0x200 waiting for monitor\
entry [0x00007fbed74f3000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.apache.log4j.Category.callAppenders(Category.java:204)
- waiting to lock <0x0000000742444ad0> (a org.apache.log4j.Logger)
at org.apache.log4j.Category.forcedLog(Category.java:391)
at org.apache.log4j.Category.info(Category.java:666)
...
我感兴趣的转储部分看起来不同(“锁定”而不是“等待锁定”)。我已经调试了很多死锁并查看了很多线程转储。我总是看到的是“等待锁定”。我从未见过“锁定”但仍“等待监视器进入”的线程,我想知道那是什么意思。
最佳答案
这是 Oracle 的 HotSpot JVM 中一个已知的表面错误。正如您所说,在您看到 - locked <0x00007f3e9a0b3830>
的堆栈跟踪中它实际上应该说 - waiting to lock <0x00007f3e9a0b3830>
因为线程还没有获得相关的锁。
参见 this bug了解更多详情。
关于java - 线程转储被阻止并锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20382091/
我是一名优秀的程序员,十分优秀!