2
JavaConcurrencyInPractice
1.1.A(Very)BriefHistoryofConcurrency
Intheancientpast,computers didn't haveoperating systems; they executed a single program from beginning to end,
andthatprogramhaddirectaccesstoalltheresourcesofthemachine.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.
Operatingsystemsevolvedto allowmore thanone programtorun atonce, running individual programs inprocesses:
isolated, independently executing programs to which the operating system allocates resources such as memory, file
handles,andsecuritycredentials.If theyneede
dto,processescouldcommuni catewithoneanotherthrougha variety
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.
Inearly timesharing systems,eachpro cess wasavirtual vonNeumanncomputer;it hadame
moryspacestoringboth
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.Nearlyallwidelyusedprogramminglangu agestodayfollowthissequentialprogrammingmodel,
wherethelanguagespecificationclearlydefines"whatcomes next"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
teakettlesandtoastersknowtheirproductsareoftenusedinanasynchronousmanner,sotheyraiseanaudiblesignal
when they complete their task. Finding the right balance of sequentiality and asynchrony is often a characteristic of
efficientpeople‐andthesameistrueofprograms.
Thesameco
ncerns(resource utilization,fairness,andconvenience) thatmotivatedthe developmentofprocessesalso
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 program
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,withunpre dictableresults.