如何程序的检测死锁发生在一个Java程序?

没有正确的解决方案

其他提示

您可以做到这一点编程方式使用ThreadMXBean附带的JDK:

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.
    }
}

显然,你应该尝试找出哪个线程执行此死锁检查 - 否则,如果该线程死锁它将无法运行检查

顺便提及,这是JConsole的是使用下盖什么。

调查一种有用的提示:

如果你能赶上应用红色手,并怀疑僵局已经出现,去按“Ctrl-BREAK”在java.exe的控制台窗口(或“按Ctrl - \”在Solaris / Linux)的。 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)
    ...

可以检测僵持线程编程方式使用ThreadMXBean的class.Here是代码,

    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");
    }

点击这里关于如何检测更多信息的死锁线程。

JArmus 是用于检测和避免死锁的库。它包括支持: Thread.joinCyclicBarrierCountDownLatchPhaserReentrantLock

要使用JArmus您需要的仪器代码。无论是通过其仪表类中的一个或与JArmus instrumentar jarmusc自动

java -jar jarmusc.jar yourprogram.jar checkedprogram.jar

输入yourprogram.jar是要检查程序。 输出与检查相同的程序来自动找到任何死锁。

壁垒需要一些帮助

与类CyclicBarrierCountDownLatchPhaser验证死锁是有点麻烦---例如,JConsole的不能检测这些类型的死锁。 JArmus需要您的一点帮助:你必须指定哪些线程同步的影响,我们称这些的注册的线程。

只要可能,注册该线程必须标记本身。一个很好的纪念注册线程是开头方法Runnable.run JArmus.register(latch);

实施例

下面的程序的死锁被正确识别通过 JArmus:

final CountDownLatch latch = new CountDownLatch(2);
final CyclicBarrier barrier = new CyclicBarrier(2);
final Queue<Exception> exceptions = new ArrayDeque<>();
Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            JArmus.register(barrier); // do not forget to register!
            JArmus.register(latch); // do not forget to register!
            latch.countDown();
            latch.await();
            barrier.await();
        } catch (Exception e) {
            exceptions.add(e);
        }
    }
});
Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            JArmus.register(barrier); // do not forget to register!
            JArmus.register(latch); // do not forget to register!
            barrier.await();
            latch.countDown();
            latch.await();
        } catch (Exception e) {
            exceptions.add(e);
        }
    }
});
t1.start();
t2.start();

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

如果你不需要编程检测可以通过这样做的 JConsole的;线程选项卡上有一个“死锁检测”按钮。在此JDK6检测两个固有监视器和j.u.c Locks锁

经由$JAVA_HOM/bin/jconsole命令运行了JConsole的

有是代码在这里: http://www.java2s.com /Code/Java/Development-Class/PerformingdeadlockdetectionprogrammaticallywithintheapplicationusingthejavalangmanagementAPI.htm

在魔术发生在ThreadMonitor.findDeadlock()

  public boolean findDeadlock() {
    long[] tids;
    if (findDeadlocksMethodName.equals("findDeadlockedThreads")
        && tmbean.isSynchronizerUsageSupported()) {
      tids = tmbean.findDeadlockedThreads();
      if (tids == null) {
        return false;
      }

      System.out.println("Deadlock found :-");
      ThreadInfo[] infos = tmbean.getThreadInfo(tids, true, true);
      for (ThreadInfo ti : infos) {
        printThreadInfo(ti);
        printLockInfo(ti.getLockedSynchronizers());
        System.out.println();
      }
    } else {
      tids = tmbean.findMonitorDeadlockedThreads();
      if (tids == null) {
        return false;
      }
      ThreadInfo[] infos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE);
      for (ThreadInfo ti : infos) {
        // print thread information
        printThreadInfo(ti);
      }
    }

    return true;
  }

这个调用,其具有在Java中5和6不同的名称(因此外ThreadMXBean)的if()的API。

的代码示例还允许中断锁,因此甚至可以打破僵局。

的Tempus-福吉特还实现其与编程螺纹倾倒类一起。它使用上述的mbean机构实现,并且在提供的下降,外的现成超级骗子溶液。

如果你希望它在运行时进行,您可以使用看门狗为这一点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top