Java Reference
In-Depth Information
java.util.concurrent.locks
provides two alternatives:
ReentrantLock
and
ReentrantReadWriteLock
. These classes provide more flexibility than
Object
but are a bit more
cumbersome to use. They cannot be used with a
synchronized
block, but must be acquired and
released explicitly with the aid of a
TRy
-
finally
statement.
The most straightforward way to fix the program is to add a private
lock
field of type
Object
and to
synchronize on this object in the
quit
and
keepWorking
methods. With these changes, the program
prints
Beer is good
as expected. The correct behavior of the program is not dependent on its
obeying the time line shown in our previous analysis:
private final Object lock = new Object();
// It's quitting time, wait for worker - Called by good boss
void quit() throws InterruptedException {
synchronized (lock) {
quittingTime = true;
join();
}
}
// Rescind quitting time - Called by evil boss
void keepWorking() {
synchronized (lock) {
quittingTime = false;
}
}
It is also possible to fix the program by having the
Worker
class implement
Runnable
rather than
extending
THRead
, and creating each worker thread using the
THRead(Runnable)
constructor. This
decouples the lock on each
Worker
instance from the lock on its
Thread
instance. It is a larger
refactoring and is left as an exercise to the reader.
Just as a library class's use of a lock can interfere with an application, an application's use of a lock
Search WWH ::
Custom Search