2
JavaConcurrencyInPractice
1.1.A(Very)BriefHistoryofConcurrency
Intheancientpast,computers didn't haveoperating systems; they executeda single programfrombeginningtoend,
andthatpro gramhaddirectaccesstoalltheresourcesofthemachine.Notonlywasitdifficulttowriteprogramsthat
ran on the bare metal, but running only a single program at a time was an inefficient use of ex
pensive and scarce
computerresources.
Operatingsystems evolvedtoallowmorethanone programtorunatonce,runningindividualprogramsinprocesses:
isolated, independently executing programs to which the operating system allocates resources such as memory, file
handles,and securitycredentials.Iftheyneede
dto,processescouldcommunicatewithoneanotherthrough avariety
ofcoarseͲgrainedcommunicationmechanisms:sockets,signalhandlers,sharedmemory,semaphores,andfiles.
Several motivating factors led to the development of operating systems that allowed multiple programs to execute
simultaneously:
Resource utilization. Programs sometimes have to wait for ex
ternal operations such as input or output, and while
waitingcandonousefulwork.Itismoreefficienttousethatwaittimetoletanotherprogramrun.
Fairness. Multiple users and programs may have equal claims on the machine's resources. It is preferable to let them
sharethecomputerviafinerͲgraine
dtimeslicingthantoletoneprogramruntocompletionandthenstartanother.
Convenience. It is often easier or more desirable to write sever
al programs that each perform a single task and have
themcoordinatewitheachotherasnecessarythantowriteasingleprogramthatperformsallthetasks.
Inearlytimesharingsystems,each processwasavirtual vonNeumanncomputer;ithad ame
moryspace storingboth
instructions and data, executing instructions sequentially according to the semantics of the machine language, and
interacting with the outside world via the operating system through a set of I/O primitives. For each instruction
executedtherewasaclearlydefined"nextinstruction",andcontrolflowedthroughtheprogramaccordingtother
ules
oftheinstructionset.Nearlyallwidelyusedprogramminglanguagestodayfollowthissequentialprogrammingmodel,
wherethelanguagespecificationclearlydefines"whatcomesnext"afteragivenactionisexecuted.
Thesequentialprogrammingmodelisintuitiveandnatural,asitmodelsthewayhumanswor
k:doonethingatatime,
in sequence mostly. Get out of bed, put on your bathrobe, go downstairs and start the tea. As in programming
languages, each of these realͲworld actions is an abstraction for a sequence of finerͲgrained actionsͲopen the
cupboard,selectaflavoroftea,measuresometeaintothepot,seeifthere'senoughwaterinthetea
kettle,ifnotput
somemorewaterin,setitonthestove,turnthestoveon,waitforthewatertoboil,andsoon.ThislaststepͲwaiting
forthewatertoboilͲalsoinvolvesadegreeofasynchrony.Whilethewaterisheating,youhaveachoiceofwhattodoͲ
just wait, or do other tasks in that time such as starting th
e toast (another asynchronous task) or fetching the
newspaper, while remaining aware that your attention will so on be needed by the t
eakettle. The manufacturers of
teakettlesandtoasterskn owtheirproductsareoftenusedinanasynchronousmanner,sotheyraiseanaudiblesignal
when they complete their task. Finding the right balance of sequentiality and asynchrony is often a characteristic of
efficientpeopleͲandthesameistrueofprograms.
Thesameco
ncerns(resourceutilization,fairness,andconvenience)thatmotivatedthedevelopmentofprocessesalso
motivated the development of threads. Threads allow multiple streams of program control flow to coexist within a
process. They share processͲwide reso urces such as memory and file handles, but each thread has its own progra m
counter,stack,andlocalva
riables.Threadsalsoprovideanaturaldecompositionforexploitinghardwareparallelismon
multiprocessorsystems;multiplethreadswithinthesameprogramcanbescheduledsimultaneouslyonmultipleCPUs.
Threadsaresometimescalledlightweightprocesses,andmostmodernoperatingsystemstreatthreads,notprocesses,
as the basic units of scheduli
ng. In the absence of explicit coordination, threads execute simultaneously and
asynchronouslywithrespecttooneanother.Sincethreadssharethememoryaddressspaceoftheirowningprocess,all
threadswithinaprocesshaveaccesstothesamevariables andallocateobjectsfromthesameheap,whichallowsfinerͲ
grained da
ta sharing than interͲprocess mechanisms. But without explicit synchronization to coordinate access to
shareddata,athreadmaymodifyvariablesthatanotherthreadisinthemiddleofusing,withunpredictableresults.