How do you detect a deadlock in a running JVM? — Cracked Java
// Concurrency & Multithreading · Deadlock, Livelock & Starvation
MidTheory

How do you detect a deadlock in a running JVM?

Capture a thread dump of the running JVM and look for the JVM's deadlock report, or query it programmatically with ThreadMXBean.findDeadlockedThreads(). The JVM detects monitor (and ReentrantLock/AQS) deadlock cycles for you — it just reports rather than resolves them.

Thread dumps from outside the JVM

Given the process id, any of these prints a full dump; the JVM scans the lock graph and appends a deadlock section if a cycle exists:

jcmd <pid> Thread.print          # modern, preferred
jstack <pid>                     # classic
jstack -l <pid>                  # -l also lists java.util.concurrent ownable synchronizers
kill -3 <pid>                    # SIGQUIT -> dump goes to the process's stdout

jcmd <pid> Thread.print and jstack both emit a Found one Java-level deadlock: block naming the threads and the locks in the cycle. -l is important when ReentrantLock is involved, since those locks only show up in the ownable-synchronizers listing.

Programmatic detection

For a health endpoint or a watchdog, ask the platform MX bean directly:

ThreadMXBean mx = ManagementFactory.getThreadMXBean();
long[] ids = mx.findDeadlockedThreads();          // monitors + ownable synchronizers (e.g. ReentrantLock)
if (ids != null) {
    ThreadInfo[] infos = mx.getThreadInfo(ids, true, true);
    for (ThreadInfo info : infos) {
        System.out.println(info.getThreadName()
            + " blocked on " + info.getLockName()
            + " owned by " + info.getLockOwnerName());
    }
}
// Note: findMonitorDeadlockedThreads() finds only intrinsic-lock cycles;
// findDeadlockedThreads() covers ReentrantLock/AQS too — prefer it.

findDeadlockedThreads() returns null when there is no deadlock, so it is cheap to poll periodically and alert.

Mark your status