Deadlock Detector : Deadlock « Threads « Java






Deadlock Detector

 
/*
 * This file is part of aion-unique <aion-unique.org>.
 *
 *  aion-unique is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  aion-unique is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with aion-unique.  If not, see <http://www.gnu.org/licenses/>.
 */
//package com.aionemu.gameserver.utils;

import java.lang.management.LockInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

/**
 * @author ATracer
 */
public class DeadlockDetector implements Runnable
{

  private int          checkInterval  = 0;
  private static String    INDENT      = "    ";
  private StringBuilder    sb        = null;

  public DeadlockDetector(int checkInterval)
  {
    this.checkInterval = checkInterval * 1000;
  }

  @Override
  public void run()
  {
    boolean noDeadLocks = true;

    while (noDeadLocks)
    {
      try
      {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        long[] threadIds = bean.findDeadlockedThreads();

        if (threadIds != null)
        {
          System.out.println("Deadlock detected!");
          sb = new StringBuilder();
          noDeadLocks = false;

          ThreadInfo[] infos = bean.getThreadInfo(threadIds);
          sb.append("\nTHREAD LOCK INFO: \n");
          for (ThreadInfo threadInfo : infos)
          {
            printThreadInfo(threadInfo);
            LockInfo[] lockInfos = threadInfo.getLockedSynchronizers();
            MonitorInfo[] monitorInfos = threadInfo.getLockedMonitors();

            printLockInfo(lockInfos);
            printMonitorInfo(threadInfo, monitorInfos);
          }

          sb.append("\nTHREAD DUMPS: \n");
          for (ThreadInfo ti : bean.dumpAllThreads(true, true))
          {
            printThreadInfo(ti);
          }
          System.out.println(sb.toString());
        }
        Thread.sleep(checkInterval);
      }
      catch (Exception ex)
      {
        ex.printStackTrace();
      }
    }
  }

  private void printThreadInfo(ThreadInfo threadInfo)
  {
    printThread(threadInfo);
    sb.append(INDENT + threadInfo.toString() + "\n");
    StackTraceElement[] stacktrace = threadInfo.getStackTrace();
    MonitorInfo[] monitors = threadInfo.getLockedMonitors();

    for (int i = 0; i < stacktrace.length; i++)
    {
      StackTraceElement ste = stacktrace[i];
      sb.append(INDENT + "at " + ste.toString() + "\n");
      for (MonitorInfo mi : monitors)
      {
        if (mi.getLockedStackDepth() == i)
        {
          sb.append(INDENT + "  - locked " + mi + "\n");
        }
      }
    }
  }

  private void printThread(ThreadInfo ti)
  {
    sb.append("\nPrintThread\n");
    sb.append("\"" + ti.getThreadName() + "\"" + " Id=" + ti.getThreadId() + " in " + ti.getThreadState() + "\n");
    if (ti.getLockName() != null)
    {
      sb.append(" on lock=" + ti.getLockName() + "\n");
    }
    if (ti.isSuspended())
    {
      sb.append(" (suspended)" + "\n");
    }
    if (ti.isInNative())
    {
      sb.append(" (running in native)" + "\n");
    }
    if (ti.getLockOwnerName() != null)
    {
      sb.append(INDENT + " owned by " + ti.getLockOwnerName() + " Id=" + ti.getLockOwnerId() + "\n");
    }
  }

  private void printMonitorInfo(ThreadInfo threadInfo, MonitorInfo[] monitorInfos)
  {
    sb.append(INDENT + "Locked monitors: count = " + monitorInfos.length + "\n");
    for (MonitorInfo monitorInfo : monitorInfos)
    {
      sb.append(INDENT + "  - " + monitorInfo + " locked at " + "\n");
      sb.append(INDENT + "      " + monitorInfo.getLockedStackDepth() + " " + monitorInfo.getLockedStackFrame() + "\n");
    }
  }

  private void printLockInfo(LockInfo[] lockInfos)
  {
    sb.append(INDENT + "Locked synchronizers: count = " + lockInfos.length + "\n");
    for (LockInfo lockInfo : lockInfos)
    {
      sb.append(INDENT + "  - " + lockInfo + "\n");
    }
  }
}

   
  








Related examples in the same category

1.Demonstrates how deadlock can be hidden in a program
2.Another deadlock demoAnother deadlock demo
3.ReentrantLock: test for deadlocksReentrantLock: test for deadlocks
4.Deadlock DetectingDeadlock Detecting
5.Using interrupt() to break out of a blocked thread.Using interrupt() to break out of a blocked thread.
6.DeadLock Detector 2