Java Reference
In-Depth Information
itions for each event that enables (maybe) a single thread to make progress. (In the worst
case, using
notify-All
results in
O
(
n
2
) wakeups where
n
would suffice.) This is another
situation where performance concerns support one approach and safety concerns support the
other.
The notification done by
put
and
take
in
BoundedBuffer
is conservative: a notification
is performed every time an object is put into or removed from the buffer. This could be op-
timized by observing that a thread can be released from a wait only if the buffer goes from
empty to not empty or from full to not full, and notifying only if a
put
or
take
effected one
of these state transitions. This is called
conditional notification.
While conditional notifica-
tion can improve performance, it is tricky to get right (and also complicates the implementa-
tion of subclasses) and so should be used carefully.
Listing 14.8
illustrates using conditional
notification in
BoundedBuffer
.
put
.
Single notification and conditional notification are optimizations. As always, follow the prin-
ciple “First make it right, and then make it fast—
if
it is not already fast enough” when using
these optimizations; it is easy to introduce strange liveness failures by applying them incor-
rectly.
Listing 14.8. Using Conditional Notification in
BoundedBuffer.put
.
14.2.5. Example: A Gate Class
of one, creating a
binary latch
: one with two states, the initial state and the terminal state.
The latch prevents threads from passing the starting gate until it is opened, at which point all
the threads can pass through. While this latching mechanism is often exactly what is needed,
sometimes it is a drawback that a gate constructed in this manner cannot be reclosed once
opened.