Java Reference
In-Depth Information
OneShotLatch is a fully functional, usable, performant synchronizer, implemented in only
twenty or so lines of code. Of course, it is missing some useful features—such as timed ac-
quisition or the ability to inspect the latch state—but these are easy to implement as well,
since AQS provides timed versions of the acquisition methods and utility methods for com-
mon inspection operations.
OneShotLatch could have been implemented by extending AQS rather than delegating to
it, but this is undesirable for several reasons [EJ Item 14]. Doing so would undermine the
simple (two-method) interface of OneShotLatch , and while the public methods of AQS
won't allow callers to corrupt the latch state, callers could easily use them incorrectly. None
of the synchronizers in java.util.concurrent extends AQS directly—they all deleg-
ate to private inner subclasses of AQS instead.
14.6. AQS in Java.util.concurrent Synchronizer Classes
Many of the blocking classes in java.util.concurrent , such as ReentrantLock ,
Semaphore , ReentrantReadWriteLock , CountDownLatch , Synchron-
ousQueue , and FutureTask , are built using AQS. Without getting too deeply into the
details (the source code is part of the JDK download [13] ) , let's take a quick look at how each
of these classes uses AQS.
14.6.1. ReentrantLock
ReentrantLock supports only exclusive acquisition, so it implements tryAcquire ,
tryRelease , and isHeldExclusively ; tryAcquire for the nonfair version is
shown in Listing 14.15 . ReentrantLock uses the synchronization state to hold the lock
acquisition count, and maintains an owner variable holding the identity of the owning thread
that is modified only when the current thread has just acquired the lock or is just about to
release it. [14] In tryRelease , it checks the owner field to ensure that the current thread
owns the lock before allowing an unlock to proceed; in tryAcquire , it uses this field to
differentiate between a reentrant acquisition and a contended acquisition attempt.
When a thread attempts to acquire a lock, tryAcquire first consults the lock state. If it
is unheld, it tries to update the lock state to indicate that it is held. Because the state could
have changed since it was first inspected a few instructions ago, tryAcquire uses com-
pareAndSetState to attempt to atomically update the state to indicate that the lock is
now held and confirm that the state has not changed since last observed. (See the description
of compareAndSet in Section 15.3 .) If the lock state indicates that it is already held, if the
Search WWH ::




Custom Search