Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java LockSupport: park only inside a checked condition loop

Last updated: 5 Oct 20265 min read
tutorial
AdvancedBy AITrove Editorial

LockSupport gives each thread at most one park permit. unpark can arrive before park, and park can return for timeout, interruption, or no reported reason.

Operational contract

This one-waiter gate publishes its waiting thread in a volatile field before checking the volatile ready flag. signal publishes ready first, then unparks the registered waiter. The waiting loop always rechecks ready after park; a wakeup alone does not prove the state changed. The deadline limits waiting to three seconds. A pre-existing interrupt returns false without consuming the interrupt status. This low-level primitive is best reserved for synchronization implementations; a CountDownLatch is simpler for ordinary one-shot application gates.

Failure case

A release signal arrives just before the worker parks. The ready flag lets the worker proceed without sleeping. A spurious wakeup while ready remains false sends it around the loop. A missing signal eventually reaches its timeout rather than blocking forever.

Java code

Java
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;

public class OneWaiterDispatchGate {
    private final AtomicReference<Thread> waiter = new AtomicReference<>();
    private volatile boolean ready;

    public boolean await() {
        Thread current = Thread.currentThread();
        if (!waiter.compareAndSet(null, current))
            throw new IllegalStateException("Only one waiter is supported");
        long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(3);
        try {
            while (!ready) {
                if (current.isInterrupted()) return false;
                long remaining = deadline - System.nanoTime();
                if (remaining <= 0) return false;
                LockSupport.parkNanos(this, remaining);
            }
            return true;
        } finally {
            waiter.compareAndSet(current, null);
        }
    }

    public void signal() {
        ready = true;
        LockSupport.unpark(waiter.get());
    }
}

Performance and ownership cost

The condition check and permit transfer use O(1) application state. Waiting consumes scheduling time until signal, interrupt, or the three-second deadline. This is a one-shot, single-waiter gate; resetting it or supporting many waiters requires more state and an explicit race policy.

Common Mistakes

  • Do not treat a return from park as proof that the condition holds.
  • Do not assume permits accumulate beyond one.
  • Do not use a one-waiter field to coordinate multiple waiting threads.

Connected lessons

java
thread state and metrics
locksupport-condition-loop
Storage details