Java Reference
In-Depth Information
beingwithdrawnthanisavailableforwithdrawal.Withoutthismethodcall,youmight
have to execute the application hundreds of times (or more) to witness this problem,
because the scheduler might rarely pause a thread between the
amount <= bal-
ance
expressionandthe
balance -= amount;
expressionstatement—the code
executes rapidly.
Consider the following scenario:
• The Husband thread executes
withdraw()
's
amount <= balance
ex-
pression,whichreturnstrue.TheschedulerpausestheHusbandthreadandlets
the Wife thread execute.
• The Wife thread executes
withdraw()
's
amount <= balance
expres-
sion, which returns true.
• TheWifethreadperformsthewithdrawal.TheschedulerpausestheWifethread
and lets the Husband thread execute.
• The Husband thread performs the withdrawal.
Thisproblemcanbecorrectedbysynchronizingaccessto
withdraw()
sothatonly
onethreadatatimecanexecuteinsidethismethod.Yousynchronizeaccessatthemeth-
od level by adding reserved word
synchronized
to the method header prior to the
method's return type; for example,
synchronized boolean withdraw(int
amount)
.
As I demonstrate later, you can also synchronize access to a block of statements by
specifying
synchronized(
object
) { /* synchronized statements
*/ }
,where
object
isanarbitraryobjectreference.Nothreadcanenterasynchron-
izedmethodorblockuntilexecutionleavesthemethod/block;thisisknownas
mutual
exclusion
.
Synchronizationisimplementedintermsofmonitorsandlocks.A
monitor
isacon-
currencyconstructforcontrollingaccesstoa
critical section
,aregionofcodethatmust
executeatomically.Itisidentifiedatthesourcecodelevelasasynchronizedmethodor
a synchronized block.
A
lock
is a token that a thread must acquire before a monitor allows that thread to
executeinsideamonitor'scriticalsection.Thetokenisreleasedautomaticallywhenthe
threadexitsthemonitor,togiveanotherthreadanopportunitytoacquirethetokenand
enter the monitor.
Note
Athreadthathasacquiredalockdoesnotreleasethislockwhenitcallsone
of
Thread
's
sleep()
methods.