Java Reference
In-Depth Information
a.deposit(100.00);
BankAccount b = new BankAccount();
Teller t1 = new Teller(a, b);
Teller t2 = new Teller(b, a);
t1.start();
t2.start();
try {
t1.join();
t2.join();
}catch(InterruptedException e) {}
System.out.println(“a balance = “ + a.getBalance());
System.out.println(“b balance = “ + b.getBalance());
}
}
The output varies depending on the environment, but deadlock can occur immediately, in
which case the output is
Making a deposit: 100.0
Here is what happens: the deposit of $100.00 is successfully made on
BankAccount a
,
but the two
Teller
threads deadlock before any other output occurs. The
t1
thread grabs
the lock on
a
, then yields. The
t2
thread grabs the lock on
b
, then yields. The
t1
thread
now attempts to acquire the
b
lock, but
t2
owns it, so
t1
becomes blocked. The
t2
thread
attempts to acquire the
a
lock, but
t1
owns it so
t2
becomes blocked. Neither thread will
ever become runnable again because the locks they are waiting for will never be freed. In
addition, the main thread of the
DeadlockDemo
program is also blocked forever because it
called
join
on both
t1
and
t2
, and neither of those two threads can run to completion.
Starting threads is easy but working with them can be diffi cult. The
BankAccount
example shown here is the typical example used to demonstrate deadlock. By the way,
there are several fi xes to this problem. One common design pattern is to order your
locks. If a thread needs multiple locks, then those objects should have some type of
ordering so that all threads ask for multiple locks in the same order. For example, when
t1
and
t2
needed the
a
and
b
locks, both threads should have attempted to acquire the
a
lock fi rst. When the
t2
thread attempts to grab the
a
lock and
t1
already owns it,
t2
is
blocked but does not own any monitor locks, leaving the
b
lock available for the
t1
thread
to complete its task successfully and avoid this deadlock scenario.
Search WWH ::
Custom Search