Java Reference
In-Depth Information
Why create a new locking mechanism that is so similar to intrinsic locking? Intrinsic locking
works fine in most situations but has some functional limitations—it is not possible to inter-
rupt a thread waiting to acquire a lock, or to attempt to acquire a lock without being will-
ing to wait for it forever. Intrinsic locks also must be released in the same block of code in
which they are acquired; this simplifies coding and interacts nicely with exception handling,
but makes non-blockstructured locking disciplines impossible. None of these are reasons to
abandon
synchronized
, but in some cases a more flexible locking mechanism offers bet-
ter liveness or performance.
plicated than using intrinsic locks: the lock
must
be released in a
finally
block. Otherwise,
the lock would never be released if the guarded code were to throw an exception. When using
locking, you must also consider what happens if an exception is thrown out of the
try
block;
if it is possible for the object to be left in an inconsistent state, additional
try-catch
or
try-finally
blocks may be needed. (You should always consider the effect of exceptions
when using any form of locking, including intrinsic locking.)
Failing to use
finally
to release a
Lock
is a ticking time bomb. When it goes off, you
will have a hard time tracking down its origin as there will be no record of where or when
the
Lock
should have been released. This is one reason not to use
ReentrantLock
as a
blanket substitute for
synchronized
: it is more “dangerous” because it doesn't automatic-
ally clean up the lock when control leaves the guarded block. While remembering to release
Listing 13.2. Guarding Object State Using
ReentrantLock
.