Skip to main content
  1. Java Concurrency (java.util.concurrent)/

LockSupport

2 mins

LockSupport is the “secret sauce” behind almost every blocking synchronizer in the java.util.concurrent package. It provides the low-level park() and unpark() primitives for thread suspension.

Source Code #

View Source on GitHub

Mechanism: The “Binary Permit” #

Each thread that uses LockSupport is associated with a single binary permit (0 or 1). Unlike a Semaphore, the permit doesn’t accumulate; it can only be 0 (no permit) or 1 (permit available).

public static void park(Object blocker) {
    Thread t = Thread.currentThread();
    setBlocker(t, blocker);
    U.park(false, 0L);
    setBlocker(t, null);
}

public static void unpark(Thread thread) {
    if (thread != null)
        U.unpark(thread);
}

When a thread calls park(), it checks its permit. If it is 1, it consumes the permit and returns immediately. If it is 0, the thread is suspended (parked). When a thread calls unpark(t), it sets the permit for thread t to 1 and wakes up the thread if it was parked.

Canonical Usage #

When to use: You almost never use LockSupport in application code. Instead, you use it when building custom synchronizers or low-level primitives where you need to suspend a thread and wake it up from another thread without using wait() and notify().

Common Patterns:

  • AQS Internal Management: Used by AbstractQueuedSynchronizer to park threads in the CLH wait queue.
  • Custom Thread Suspension: In systems where you need to suspend a specific thread and be sure it will only wake up when a specific event occurs.
// Suspending the current thread
LockSupport.park(this); // Park current thread, associating it with "this" object

// Resuming a specific thread from another thread
LockSupport.unpark(workerThread); // Signal workerThread to wake up

Advantages Over wait() and notify() #

  • No Monitor Requirement: park() and unpark() do not require the caller to hold a specific object monitor (no synchronized block).
  • Resilience to Race Conditions: If unpark() is called before park(), the next park() will return immediately. This eliminates the “lost wake-up” problem common with wait() and notify().
  • Debugging Support: park(blocker) allows you to associate an object with the parked thread, which is visible in thread dumps (e.g., via jstack).