java中的程序化死锁检测

57 java concurrency multithreading deadlock

如何以编程方式检测Java程序中是否发生了死锁?

Ada*_*ski 61

您可以使用ThreadMXBeanJDK附带的编程方式执行此操作:

ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long[] threadIds = bean.findDeadlockedThreads(); // Returns null if no threads are deadlocked.

if (threadIds != null) {
    ThreadInfo[] infos = bean.getThreadInfo(threadIds);

    for (ThreadInfo info : infos) {
        StackTraceElement[] stack = info.getStackTrace();
        // Log or store stack trace information.
    }
}
Run Code Online (Sandbox Code Playgroud)

显然你应该尝试隔离执行此死锁检查的任何线程 - 否则,如果该线程死锁,它将无法运行检查!

顺便说一句,这就是JConsole在封面下使用的内容.

  • 该方法的Javadoc说它可能很昂贵.你碰巧知道有多贵吗? (4认同)

Nic*_*net 12

一个有用的调查提示:

如果您可以抓住应用程序并且怀疑发生了死锁,请在java.exe控制台窗口(或Solaris/Linux上的"Ctrl- \")中按"Ctrl-Break".jvm将转储所有线程的当前状态和堆栈跟踪,找出死锁并精确描述它们.

它看起来像这样:

Full thread dump Java HotSpot(TM) Client VM (1.5.0_09-b03 mixed mode):

"[Test Timer] Request Queue" prio=6 tid=0x13d708d0 nid=0x1ec in Object.
    wait() [0x1b00f000..0x1b00fb68]
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at library.util.AsyncQueue.run(AsyncQueue.java:138)
        - locked <0x02e70000> (a test.server.scheduler.SchedulerRequestQueue)

    ...

Found one Java-level deadlock:
=============================
"Corba service":
  waiting to lock monitor 0x13c06684 (object 0x04697d90, a java.lang.Object),
  which is held by "[Server Connection] Heartbeat Timer"
"[Server Connection] Heartbeat Timer":
  waiting to lock monitor 0x13c065c4 (object 0x0467e728, a test.proxy.ServerProxy), which is held by "Corba service"

Java stack information for the threads listed above:
===================================================
"Corba service":
    at test.proxy.ServerProxy.stopHBWatchDog(ServerProxy:695)
    - waiting to lock <0x04697d90> (a java.lang.Object)
    ...
Run Code Online (Sandbox Code Playgroud)

  • 实际上你想要的是发送一个"QUIT"信号(即一个SIGQUIT)但它并不是一个'QUIT'.Java应用程序上的OS X,Linux(和Solaris)上的SIGQUIT会转储堆栈跟踪.Ctrl + \是发送SIGQUIT的一种方式.拿着pid做:*kill -3 {id}*是另一种方法. (2认同)

小智 5

您可以使用 ThreadMXBean 类以编程方式检测死锁线程。这是代码,

    ThreadMXBean bean = ManagementFactory.getThreadMXBean();

    long ids[] = bean.findMonitorDeadlockedThreads();

    if(ids != null)
    {
        ThreadInfo threadInfo[] = bean.getThreadInfo(ids);

        for (ThreadInfo threadInfo1 : threadInfo)
        {
            System.out.println(threadInfo1.getThreadId());    //Prints the ID of deadlocked thread

            System.out.println(threadInfo1.getThreadName());  //Prints the name of deadlocked thread

            System.out.println(threadInfo1.getLockName());    //Prints the string representation of an object for which thread has entered into deadlock.

            System.out.println(threadInfo1.getLockOwnerId());  //Prints the ID of thread which currently owns the object lock

            System.out.println(threadInfo1.getLockOwnerName());  //Prints name of the thread which currently owns the object lock.
        }
    }
    else
    {
        System.out.println("No Deadlocked Threads");
    }
Run Code Online (Sandbox Code Playgroud)

单击此处了解有关如何检测死锁线程的更多信息。


Ric*_*dOD 2

您可能需要考虑IBM 的 MTRAT。毕竟预防胜于治疗。多核软件开发套件还附带死锁检测工具。

  • “MTRAT”链接转到有关浮点运算的页面。很困惑这是关于什么的 (3认同)