LockSupport
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 #
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
AbstractQueuedSynchronizerto 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()andunpark()do not require the caller to hold a specific object monitor (nosynchronizedblock). - Resilience to Race Conditions: If
unpark()is called beforepark(), the nextpark()will return immediately. This eliminates the “lost wake-up” problem common withwait()andnotify(). - Debugging Support:
park(blocker)allows you to associate an object with the parked thread, which is visible in thread dumps (e.g., viajstack).