How do you read a thread dump to confirm a deadlock? — Cracked Java
// Concurrency & Multithreading · Deadlock, Livelock & Starvation
MidTheory

How do you read a thread dump to confirm a deadlock?

Look for the Found one Java-level deadlock: block the JVM appends to a thread dump. It names each thread in the cycle, the lock it is waiting to lock, and which thread already holds it — trace those "owned by" arrows and confirm they form a loop.

Generating the dump

jcmd <pid> Thread.print     # or: jstack -l <pid>   (-l shows ReentrantLock owners)

Reading the deadlock section

After the per-thread stacks, the JVM prints an explicit analysis. For the two-lock example (T1 takes A→B, T2 takes B→A):

Found one Java-level deadlock:
=============================
"T1":
  waiting to lock monitor 0x00007f... (object 0x000000071, a java.lang.Object),
  which is held by "T2"
"T2":
  waiting to lock monitor 0x00007f... (object 0x000000070, a java.lang.Object),
  which is held by "T1"

Java stack information for the threads listed above:
===================================================
"T1":
        at TwoLockDeadlock.lambda$main$0(TwoLockDeadlock.java:11)
        - waiting to lock <0x000000071> (a java.lang.Object)   // LOCK_B
        - locked <0x000000070> (a java.lang.Object)            // LOCK_A
"T2":
        at TwoLockDeadlock.lambda$main$1(TwoLockDeadlock.java:21)
        - waiting to lock <0x000000071...>                     // wants LOCK_A 0x...70
        - locked <0x000000071> (a java.lang.Object)            // LOCK_B

How to read it:

  • The summary block is the cycle. "T1 ... held by T2" and "T2 ... held by T1" close the loop — that is the proof of deadlock.
  • locked <addr> = a monitor this thread currently owns. waiting to lock <addr> = a monitor it is blocked trying to acquire.
  • Match the hex addresses. The address T1 is waiting to lock equals the address T2 has locked, and vice versa. The matching identities are what prove the cycle, not the names.
  • Each thread's state shows as BLOCKED (on object monitor). For ReentrantLock, you instead see parking to wait for ... AbstractQueuedSynchronizer, and you need jstack -l to see the owner in the "Locked ownable synchronizers" list.

Mark your status