Mastering Java’s Unsafe park/unpark and AQS: Build Custom Locks with LockSupport
This article explains how Java’s Unsafe class provides low‑level park and unpark methods, how the LockSupport utility wraps them for easier use, and demonstrates building a simple exclusive lock with AbstractQueuedSynchronizer, covering state handling, blocking mechanisms, and thread‑queue management.
Unsafe park and unpark
Unsafe defines two native methods that are the low‑level primitives for thread blocking:
public native void park(boolean isAbsolute, long time);
public native void unpark(Object thread); parkblocks the current thread. The first boolean indicates whether the second argument is an absolute deadline ( true) or a relative timeout ( false). unpark wakes a thread that was previously blocked by park. The argument is the thread object to be unblocked.
LockSupport
The java.util.concurrent.locks package provides LockSupport as a convenient wrapper around the Unsafe primitives. Internally it calls Unsafe.park and Unsafe.unpark, so developers can avoid dealing with native signatures directly.
LockSupport also supports attaching a blocker object to a thread for debugging. It does this by using Unsafe.putObject to set the private Thread.parkBlocker field, which can later be read by diagnostic tools.
AbstractQueuedSynchronizer (AQS)
Most Java synchronizers—such as ReentrantLock, ReentrantReadWriteLock, Semaphore, and CountDownLatch —are built on the AbstractQueuedSynchronizer framework. The original design paper is available at http://gee.cs.oswego.edu/dl/papers/aqs.pdf.
Hand‑written exclusive lock using AQS
A minimal exclusive lock can be created by extending AQS with an inner Sync class and implementing the two core methods tryAcquire and tryRelease. The outer lock class then delegates lock() to sync.acquire(1) and unlock() to sync.release(1). The following example, called SimpleLock , demonstrates this pattern:
When a thread acquires the lock, all other threads are placed into the AQS wait queue.
When the owning thread releases the lock, the first queued thread is unblocked and attempts to acquire the lock.
The result shows that a few lines of AQS‑based code provide full mutex semantics.
AQS core principles
State value and atomic operations
private volatile int state;
protected final int getState() { return state; }
protected final void setState(int newState) { state = newState; }
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}The state field represents the synchronizer's current condition. It is a volatile int so that reads see the latest value, and updates are performed atomically via CAS (compare‑and‑set) provided by Unsafe.compareAndSwapInt.
If state == 0, the synchronizer is in the released state and threads may acquire it.
If state != 0, the synchronizer is acquired . Subsequent threads join the wait queue. Re‑entrant synchronizers increment state to count recursive acquisitions.
Implementations may assign custom meanings to bits of state (e.g., separate read/write counters for a read‑write lock).
Blocking and unblocking
All blocking operations in AQS delegate to LockSupport . LockSupport.park puts the current thread into the wait set, and LockSupport.unpark wakes a specific thread. Because LockSupport itself uses Unsafe.park and Unsafe.unpark, the entire blocking mechanism ultimately relies on the Unsafe primitives.
Thread wait queue
AQS maintains a FIFO queue of Node objects. Each node stores a reference to the waiting thread, its wait status, and links to predecessor and successor nodes. The queue guarantees fair ordering for threads that cannot acquire the synchronizer immediately.
Source repository for the examples: https://github.com/Wasabi1234/Java-Concurrency-Programming-Tutorial
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JavaEdge
First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
