Java Reference
In-Depth Information
locked (which it does by searching the
is-waiting-for
graph for cycles), it picks a victim and
aborts that transaction. This releases the locks held by the victim, allowing the other transac-
tions to proceed. The application can then retry the aborted transaction, which may be able to
complete now that any competing transactions have completed.
The JVM is not nearly as helpful in resolving deadlocks as database servers are. When a set
of Java threads deadlock, that's the end of the game—those threads are permanently out of
commission. Depending on what those threads do, the application may stall completely, or a
particular subsystem may stall, or performance may suffer. The only way to restore the ap-
plication to health is to abort and restart it—and hope the same thing doesn't happen again.
Like many other concurrency hazards, deadlocks rarely manifest themselves immediately.
The fact that a class has a potential deadlock doesn't mean that it ever
will
deadlock, just that
it can. When deadlocks do manifest themselves, it is often at the worst possible time—under
heavy production load.
10.1.1. Lock-ordering Deadlocks
rightLeft
methods each acquire the
left
and
right
locks. If one thread calls
leftRight
and another calls
rightLeft
, and their actions are interleaved as shown in
Figure 10.1
,
they will deadlock.
Figure 10.1. Unlucky Timing in
LeftRightDeadlock
.
The deadlock in
LeftRightDeadlock
came about because the two threads attempted to
acquire the same locks in a
differentorder
. If they asked for the locks in the same order, there
would be no cyclic locking dependency and therefore no deadlock. If you can guarantee that
every thread that needs locks
L
and
M
at the same time always acquires
L
and
M
in the same
order, there will be no deadlock.