Java Reference
In-Depth Information
C produced by producer.
C consumed by consumer.
D produced by producer.
D consumed by consumer.
Caution
Never call
wait()
outside of a loop. The loop tests the condition
(
!writeable
or
writeable
inthepreviousexample)beforeandafterthe
wait()
call.Testingtheconditionbeforecalling
wait()
ensures
liveness
.Ifthistestwasnot
present,andiftheconditionheldand
notify()
hadbeencalledpriorto
wait()
be-
ingcalled,itisunlikelythatthewaitingthreadwouldeverwakeup.Retestingthecon-
ditionaftercalling
wait()
ensures
safety
.Ifretestingdidnotoccur,andifthecondi-
tiondidnotholdafterthethreadhadawakenedfromthe
wait()
call(perhapsanoth-
erthreadcalled
notify()
accidentally whenthecondition didnothold),thethread
would proceed to destroy the lock's protected invariants.
Toomuchsynchronizationcanbeproblematic.Ifyouarenotcareful,youmighten-
counterasituationwherelocksareacquiredbymultiplethreads,neitherthreadholdsits
ownlockbutholdsthelockneededbysomeotherthread,andneitherthreadcanenter
andlaterexititscriticalsectiontoreleaseitsheldlockbecausesomeotherthreadholds
thelocktothatcriticalsection.
Listing4-28
'satypicalexampledemonstratesthisscen-
ario, which is known as
deadlock
.
Listing 4-28.
A pathological case of deadlock
class Deadlock
{
private Object lock1 = new Object();
private Object lock2 = new Object();
void instanceMethod1()
{
synchronized(lock1)
{
synchronized(lock2)
{
System.out.println("first
thread
in
in-
stanceMethod1");
// critical section guarded first by
// lock1 and then by lock2
}