What is AbstractQueuedSynchronizer
in Java's concurrent.locks
package used for? Can someone shed some light on its methods doAcquireInterruptibly
and parkAndCheckInterrupt
?
What is AbstractQueuedSynchronizer in concurrent.locks package used for
The AbstractQueuedSynchronizer is the building blocks for synchronization constructs that are used and implemented (at the very least) in the java.util.concurrency package.
For instance, the ReentrantLock delegates to a Sync which extends AbstractQueuedSynchronizer. If you were to write your own lock it could look like this
public class MyLock extends AbstractQueuedSynchronizer implements Lock{
@Override
public void lock() {
super.acquire(1);
}
@Override
public void unlock() {
if(Thread.currentThread() != super.getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
super.release(1);
}
}
So here the MyLock class will inherit the low level functionality of thread suspension & queuing to the AQS while handling any special functionality itself (for instance this lock requires the thread owning the lock to be the one releasing it but a Semaphore does not).
Can someone throw some light on its methods doAcquireInterruptibly and parkAndCheckInterrupt
Note: These methods are private to the class so the actual functionality is able to change between different version or different implementations. The default provided functionality at the moment I am explaining are as follows:
doAcquireInterruptibly
Will try to be the exclusive owner of this sync. It will do this for ever until the thread is interrupted or successfully acquires. Consider a thread trying to enter a synchronized
block, the thread will sit there and wait forever until it enters the monitor (no thread currently owns or the owning thread exists the monitor). The advantage here is that the acquiring thread can be interrupted.
parkAndCheckInterrupt
Just a convenience method that will suspend (park) a thread, return while resetting the interrupted status.
AbstractQueuedSynchronizer: It provides a framework for implementing blocking locks and related synchronizers like semaphores, CountDownLatch etc. The basic algorithm for acquire is try acquire, if successful return else enqueue thread, if it is not already queued and block the current thread. Similarly basic algorithm for release is try release, if successful, unblock the first thread in the queue else simply return. The threads will wait in a first-in-first-out (FIFO) wait queues. The abstract methods tryAcquire and tryRelease will be implemented by subclasses based on their need.
doAcquireInterruptibly will try to acquire the lock. If the lock is already acquired by some other thread, the current thread will be blocked(parked). If it acquires the lock, it will simply return.
- parkAndCheckInterrupt will park the thread or in other words disable the thread scheduling till some other thread unblocks it. It can be due to the release of lock by the owning thread or due to some other thread interrupting it. If it is interrupted by some other thread an exception will be thrown.
I'd like to talk about AbstractQueuedSynchronizer(AQS) with some simple words.
Think about these scenarios in the real world:
- For swimmers, they can swim together in a swimming pool(shared). But for cleaner who will sanitate it with chlorine ponder, he has to wait until all the swimmers have gone(exclusive).
- For the drivers who are outside a busy parking lot, they must wait in a queue. Usually a doorkeeper controls access. A normal car will take one parking space. A Lincoln Limousine may take two or more.
As we see, there're 3 variables:
- Total resource quantity.
- How many resources every time you take.
- Access strategy(shared/exclusive).
AQS is a template class used to manage the CRITICAL SECTION, which means you can just extend it and fill in with the variables above to finish your job. Details like how to avoid race hazard or control the queue have been hidden.
For further reading, you'd better learn the source code of Mutex, Semaphore and ReentrantReadWriteLock.
© 2022 - 2024 — McMap. All rights reserved.