Java Reference
In-Depth Information
ger thread is easy enough, since it repeatedly calls
take
, which is responsive to interruption;
if the logger thread is modified to exit on catching
InterruptedException
, then inter-
rupting the logger thread stops the service.
However, simply making the logger thread exit is not a very satifying shutdown mechanism.
Such an abrupt shutdown discards log messages that might be waiting to be written to the log,
but, more importantly, threads blocked in
log
because the queue is full
will never become
unblocked
. Cancelling a producerconsumer activity requires cancelling both the producers
and the consumers. Interrupting the logger thread deals with the consumer, but because the
producers in this case are not dedicated threads, cancelling them is harder.
Another approach to shutting down
LogWriter
would be to set a “shutdown requested”
flag to prevent further messages from being submitted, as shown in
Listing 7.14
.
The con-
sumer could then drain the queue upon being notified that shutdown has been requested,
writing out any pending messages and unblocking any producers blocked in
log
. However,
this approach has race conditions that make it unreliable. The implementation of
log
is a
check-then-act sequence: producers could observe that the service has not yet been shut down
but still queue messages after the shutdown, again with the risk that the producer might get
blocked in
log
and never become unblocked. There are tricks that reduce the likelihood of
this (like having the consumer wait several seconds before declaring the queue drained), but
these do not change the fundamental problem, merely the likelihood that it will cause a fail-
ure.
Listing 7.14. Unreliable Way to Add Shutdown Support to the Logging Service.
The way to provide reliable shutdown for
LogWriter
is to fix the race condition, which
means making the submission of a new log message atomic. But we don't want to hold a
lock while trying to enqueue the message, since
put
could block. Instead, we can atomically
check for shutdown and conditionally increment a counter to “reserve” the right to submit a