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.
Listing 13.2 shows the canonical form for using a Lock . This idiomis somewhat more com-
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
the lock from a finally block is not all that difficult, it is also not impossible to forget. [1]
Listing 13.2. Guarding Object State Using ReentrantLock .
Search WWH ::




Custom Search