How to analyze a java thread dump?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A Java thread dump is a snapshot of every thread inside a JVM at a specific moment. It is one of the fastest ways to diagnose deadlocks, stuck requests, CPU spikes, and thread pool exhaustion because it shows what each thread is doing and what it is waiting for.
The most useful analysis comes from reading several dumps taken a few seconds apart. A single dump can tell you what is blocked right now, but repeated dumps reveal whether threads are making progress or stuck in the same stack frames.
Capture the Dump Correctly
You can generate a dump with jcmd, jstack, or a signal such as kill -3 on Unix-like systems.
Three dumps spaced a few seconds apart are often more valuable than one. If the same busy thread stays in the same method in all three files, that is a strong clue.
Read the Thread Header First
Each thread starts with a header that tells you the thread name, priority, native identifier, and state. The state is the first quick signal:
- '
RUNNABLEmeans the thread is eligible to run, often consuming CPU or doing I/O' - '
BLOCKEDmeans it is waiting for a monitor lock' - '
WAITINGmeans it is parked until another thread signals it' - '
TIMED_WAITINGmeans it is sleeping or waiting with a timeout'
Example excerpt:
Start by asking a simple question: is this a normal waiting thread, or a thread that should not be stuck?
Look for Repeated Problem Patterns
Blocked Threads
If many request threads are BLOCKED, find the monitor they are trying to enter and the thread that owns it. A single synchronized section around slow work can serialize your entire service.
Waiting Thread Pools
A pool full of waiting worker threads can be normal. A pool with too few workers and many pending requests is not. Match the dump with application metrics so you know whether inactivity is healthy or pathological.
Busy Loops
A thread in RUNNABLE is not automatically bad, but if the same stack trace appears in multiple dumps without moving, it may be spinning:
This kind of loop burns CPU because it polls instead of blocking. Replacing it with a blocking queue is usually better:
Identify Deadlocks and Lock Contention
The JVM can sometimes report a deadlock explicitly near the end of the dump. Even when it does not, you can still infer one by tracing which thread owns which monitor and which monitor each thread is waiting for.
If thread A waits for a lock held by thread B, and thread B waits for a lock held by thread A, you have a classic cycle. The fix is normally architectural: consistent lock ordering, smaller critical sections, or replacing nested locking with higher-level concurrency primitives.
Connect Stack Frames to Real Code
Do not stop at thread states. The important part is the top application frame. Framework code tells you where execution currently sits, but your package names usually reveal the real bottleneck.
For example, if many request threads stop at:
go read that method. Look for synchronized blocks, slow database calls, unbounded retries, or network requests made while holding a lock.
Common Pitfalls
- Analyzing only one dump and drawing strong conclusions from it. Repeated dumps are much more reliable.
- Treating every
WAITINGthread as a problem. Idle executor workers are often supposed to wait. - Focusing on framework frames and ignoring the first relevant application frame.
- Missing lock ownership details. The key clue is often the monitor line, not just the state name.
- Capturing a dump long after the incident. For transient production issues, timing matters.
Summary
- Capture several thread dumps a few seconds apart.
- Use thread states to triage, then read the top application frames closely.
- '
BLOCKEDthreads usually point to lock contention or deadlocks.' - Repeated
RUNNABLEstacks can indicate CPU-heavy loops or stuck native calls. - The best fixes usually come from correlating thread dumps with application code and runtime metrics.

