【问题标题】:What does "Number of locked synchronizers = 1" in a StackTrace mean?StackTrace 中的“锁定同步器数 = 1”是什么意思?
【发布时间】:2014-09-13 03:47:20
【问题描述】:

我目前正在处理我继承的一些代码。执行时,控制台会记录很多异常,其中一个异常如下所示:

["bg-thread-0" Id=28 RUNNABLE
    at java.util.zip.ZipFile.read(Native Method)
    at java.util.zip.ZipFile.access$1400(ZipFile.java:56)
    at java.util.zip.ZipFile$ZipFileInputStream.read(ZipFile.java:677)
    -  locked java.util.zip.ZipFile@67369c20
    at java.util.zip.ZipFile$ZipFileInflaterInputStream.fill(ZipFile.java:413)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
    at org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry.getBytes(BundleEntry.java:102)
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:511)
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:455)
    ...

    Number of locked synchronizers = 1
    - java.util.concurrent.ThreadPoolExecutor$Worker@66e5b079

]

我正在使用Logback 进行日志记录。现在我不知道该异常是在哪里生成或记录的,因为该信息已被... 截断。 我也不知道是什么意思。我猜这与死锁有关(因为Number of locked synchronizers = 1),但我不确定。

所以我的问题是:如何在这里进行?该异常是什么意思,如何调试和找到它以及如何解决它?我真的不知道,并会感谢任何提示。谢谢!

【问题讨论】:

  • 这看起来更像是一个线程转储而不是常规的堆栈跟踪。当某些东西向 JVM 进程发送 SIGQUIT 信号时,你会得到这些,
  • @StephenC:如果是这样,线程是通过什么机制被转储的?如何拦截/调试/分析找出原因?

标签: java debugging exception logging


【解决方案1】:

这看起来更像是 Java 线程转储,而不是常规的堆栈跟踪。 (我希望每个线程都能看到其中一个。)

当 JVM 外部的东西向 JVM 进程发送 SIGQUIT 信号时,您(通常)会获得 Java 线程转储。

本问答对如何追踪意外信号的来源有一些想法:

一种建议的方法是使用 Linux Audit 系统(请参阅man auditctl),另一种方法是使用 systemtap。 (我也没有这方面的经验……但我确实在这里找到了一些用于跟踪信号的 systemtap 示例:https://sourceware.org/systemtap/examples/)。


就其价值而言,“同步器”是用于实现锁的构建块类;见http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/package-summary.html。行:

Number of locked synchronizers = 1

实际上是说线程当前持有一个锁。请注意,Oracle 没有正式记录线程转储的含义,他们显然表示格式可能会因版本/发行版而异。

【讨论】:

  • 我不确定,但我认为这不正确。首先,那些转储或堆栈跟踪或它们出现在常规控制台中的任何内容,即程序的执行输出。其次,它们在启动程序时出现确定性,因此我认为不涉及其他过程。第三,使用 JStack 输出(发送到单独的控制台)看起来更像:“Signal Dispatcher”守护进程 prio=5 tid=0x00007f84e5014800 nid=0x3903 runnable [0x00000000000000000] java.lang.Thread.State: RUNNABLE
  • 1) 线程转储也转到控制台。 2) 信号可能来自 JVM 启动的进程,也可能来自 JVM 启动器。 3) 线程堆栈转储的格式是特定于 Java 版本的。
  • 如果这不是线程转储,我很想知道它实际上是什么。如果你弄明白了,请自行回答问题。
  • 感谢您的帮助。毕竟我找到了(虽然我花了一段时间)。
  • 我会接受你的回答,因为这帮助我找到了我在单独答案中发布的解决方案。
【解决方案2】:

我找到了!

在代码深处我发现了以下内容:

for (ThreadInfo threadInfo : ManagementFactory.getThreadMXBean().dumpAllThreads(true, true)) {
      System.out.println(threadInfo);
}

所以这毕竟是一个线程转储,但它是在内部触发的。感谢您的回答!

【讨论】:

    猜你喜欢
    • 2010-11-08
    • 2016-02-09
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多