Java Thread States: WAIT vs BLOCKED – Key Differences Explained with Examples

Java Thread States: WAIT vs BLOCKED – Key Differences Explained with Examples

Understanding thread states like WAIT and BLOCKED is crucial for debugging concurrency issues in Java. This guide demystifies these states, explains their differences, and shows how to identify them in code.


Thread States in Java

Java threads transition through six states during their lifecycle:

  1. NEW: Thread created but not started.
  2. RUNNABLE: Thread is executing or ready to run.
  3. BLOCKED: Thread waiting to acquire a lock.
  4. WAITING: Thread waiting indefinitely for a signal.
  5. TIMED_WAITING: Thread waiting for a specific period.
  6. TERMINATED: Thread has finished execution.

Today, we focus on WAIT vs BLOCKED.


What is the BLOCKED State?

A thread enters the BLOCKED state when it’s unable to acquire a lock held by another thread. This typically happens with synchronized blocks/methods.

Example: BLOCKED State

public class BlockedExample {
    public static void main(String[] args) {
        Object lock = new Object();

        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                // Thread t1 holds the lock
                try { Thread.sleep(5000); } catch (InterruptedException e) {}
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (lock) {
                // Thread t2 will BLOCK until t1 releases the lock
            }
        });

        t1.start();
        t2.start();
    }
}
  • t2 becomes BLOCKED while waiting for t1 to release the lock.

What is the WAITING State?

A thread enters the WAITING state when it explicitly waits for a signal via Object.wait(), Thread.join(), or LockSupport.park().

Example: WAITING State

public class WaitExample {
    public static void main(String[] args) {
        Object lock = new Object();

        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    lock.wait(); // Thread t1 enters WAITING state
                } catch (InterruptedException e) {}
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (lock) {
                lock.notify(); // Wakes up t1
            }
        });

        t1.start();
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
        t2.start();
    }
}
  • t1 enters WAITING until t2 calls notify().

Key Differences: WAIT vs BLOCKED

AspectBLOCKEDWAITING
TriggerFails to acquire a lock.Explicit call to wait(), join().
Lock StatusStill holds other locks.Releases the lock temporarily.
Exit ConditionLock becomes available.notify()/notifyAll() is called.
Scheduler ImpactActively contends for CPU resources.Dormant; minimal resource usage.

Real-World Scenarios

When to Expect BLOCKED Threads

  • Multiple threads accessing a shared synchronized resource.
  • Database connection pools with contention.

When to Expect WAITING Threads

  • Producer-consumer patterns using wait()/notify().
  • Thread coordination (e.g., waiting for a task to complete with Thread.join()).

How to Diagnose Thread States

Use tools like jstack, VisualVM, or Java Flight Recorder to capture thread dumps.

Sample Thread Dump Analysis:

"Thread-1" #12 prio=5 os_prio=0 tid=0x00007f... nid=0x3d03 in Object.wait() [0x00007f...]
   java.lang.Thread.State: WAITING (on object monitor)

"Thread-2" #13 prio=5 os_prio=0 tid=0x00007f... nid=0x3d04 blocked on lock [0x00007f...]
   java.lang.Thread.State: BLOCKED (on object monitor)

Best Practices to Avoid Thread Issues

  1. Prefer java.util.concurrent over synchronized (e.g., ReentrantLock).
  2. Use timeouts with wait(long timeout) to prevent indefinite waits.
  3. Minimize synchronized blocks to reduce contention.

FAQs

Q: Can a thread be both WAITING and BLOCKED?

No. A thread can only be in one state at a time.

Q: How does notifyAll() affect WAITING threads?

It wakes all WAITING threads, but they must re-acquire the lock (potentially becoming BLOCKED).

Q: Why does my thread dump show RUNNABLE during I/O?

The JVM marks threads in native I/O operations as RUNNABLE, even if they’re idle.


Key Takeaways

  • BLOCKED: Thread is waiting for a lock.
  • WAITING: Thread is idle until signaled.
  • Use thread dumps and modern concurrency tools to debug issues.

By understanding these states, you’ll optimize multithreaded applications and resolve issues faster.


Meta Description: Learn the difference between WAIT and BLOCKED thread states in Java. Includes code examples, thread dump analysis, and best practices for concurrency.

Tags: Java threads, WAIT vs BLOCKED, thread states, Java concurrency, synchronized, wait() and notify(), multithreading

Keywords: Java thread states, WAIT vs BLOCKED difference, thread lifecycle, synchronized block, wait() method, thread contention, Java thread dump analysis

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *