Java Reference
In-Depth Information
It is easy to develop a recloseable
ThreadGate
class using condition waits, as shown in
that blocks until the gate is opened. The
open
method uses
notifyAll
because the se-
mantics of this class fail the “one-in, one-out” test for single notification.
The condition predicate used by
await
is more complicated than simply testing
isOpen
.
This is needed because if
N
threads are waiting at the gate at the time it is opened, they should
all be allowed to proceed. But, if the gate is opened and closed in rapid succession, all threads
might not be released if
await
examines only
isOpen
: by the time all the threads receive
the notification, reacquire the lock, and emerge from
wait
, the gate may have closed again.
So
ThreadGate
uses a somewhat more complicated condition predicate: every time the
gate is closed, a “generation” counter is incremented, and a thread may pass
await
if the
gate is open now or if the gate has opened since this thread arrived at the gate.
Since
ThreadGate
only supports waiting for the gate to open, it performs notification only
in
open
; to support both “wait for open” and “wait for close” operations, it would have to
notify in both
open
and
close
. This illustrates why state-dependent classes can be fragile
to maintain—the addition of a new statedependent operation may require modifying many
code paths that modify the object state so that the appropriate notifications can be performed.
14.2.6. Subclass Safety Issues
Using conditional or single notification introduces constraints that can complicate sub-
classing [CPJ 3.3.3.3]. If you want to support subclassing at all, you must structure your class
so subclasses can add the appropriate notification on behalf of the base class if it is subclassed
in a way that violates one of the requirements for single or conditional notification.