Java Reference
In-Depth Information
14.4. Anatomy of a Synchronizer
The interfaces of ReentrantLock and Semaphore have a lot in common. Both classes
act as a “gate”, allowing only a limited number of threads to pass at a time; threads arrive at
the gate and are allowed through ( lock or acquire returns successfully), are made to wait
( lock or acquire blocks), or are turned away ( tryLock or tryAcquire returns false,
indicating that the lock or permit did not become available in the time allowed). Further, both
allow interruptible, uninterruptible, and timed acquisition attempts, and both allow a choice
of fair or nonfair queueing of waiting threads.
Given this commonality, you might think that Semaphore was implemented on top of
ReentrantLock , or perhaps ReentrantLock was implemented as a Semaphore with
one permit. This would be entirely practical; it is a common exercise to prove that a counting
semaphore can be implemented using a lock (as in SemaphoreOnLock in Listing 14.12 )
and that a lock can be implemented using a counting semaphore.
In actuality, they are both implemented using a common base class, Abstract-
QueuedSynchronizer (AQS)—as are many other synchronizers. AQS is a framework
for building locks and synchronizers, and a surprisingly broad range of synchronizers can be
built easily and efficiently using it. Not only are ReentrantLock and Semaphore built
using AQS, but so are CountDownLatch , ReentrantReadWriteLock , Synchron-
ousQueue , [12] and FutureTask .
Listing 14.11. Bounded Buffer Using Explicit Condition Variables.
Search WWH ::




Custom Search