the java memory model - rice universityjohnmc/comp522/lecture-notes/comp522-… · use volatile to...

55
The Java Memory Model Authors: Jeremy Manson, William Pugh, Sarita V. Adve Presenter: Keren Zhou COMP 522

Upload: others

Post on 24-Jun-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

TheJavaMemoryModelAuthors:JeremyManson,WilliamPugh,SaritaV.AdvePresenter:KerenZhouCOMP522

Page 2: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

WhyJavaneedsawell-formedmemorymodel• Javasupportsthreadsrunningonsharedmemory• Javamemorymodeldefinesmulti-threadedJavaprogramsemantics• Keyconcerns:Javamemorymodelspecifieslegalbehaviorsandprovidessafetyandsecurityproperties

3/26/19 2

Page 3: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

WhyshouldwecareaboutJavaMemoryModel• Aprogrammershouldknow• Juniorlevel

• Usemonitor,locks,andvolatile properly• LearnsafetyguaranteesofJava

• Intermediatelevel• Reasonthecorrectnessofconcurrentprograms• Useconcurrentdatastructures(e.g ConcurrentHashMap)

• Expertlevel• Understandandoptimizeutilitiesinjava.util.concurrent

• AbstractExecutorService• Atomicvariables

3/26/19 3

Page 4: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Createasingletontogetastaticinstance• Singleton:onlywantasingleinstanceinaprogram• Database• Logging• Configuration

3/26/19 4

public class Instance {private static Instance instance;public static Instance getInstance() {if (instance == null)instance = new Instance();

return instance;}

}

12345678

Page 5: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Thesimplesingletonisthread-unsafe

3/26/19 5

public class Instance {private static Instance instance;public static Instance getInstance() {if (instance == null)instance = new Instance();

return instance;}

}

12345678

Threads

T0

T1

Line4

Line4

Line5

Line5

Line6

Line6

getInstance

getInstance

Time Line

Createtwoinstancesatthesametime!

Page 6: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Usesynchronizedkeyword

3/26/19 6

• Javasynchronized keywordcanbeusedindifferentcontexts• Instancemethods• Codeblocks• Staticmethods

• Onlyonethreadcanexecuteinsideastaticsynchronizedmethodperclass,irrespectiveofthenumberofinstancesithas.

Page 7: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Thesynchronizedsingletonhaslowperformance

3/26/19 7

public class Instance {private static Instance instance;public synchronized static Instance getInstance() {if (instance == null)instance = new Instance();

return instance;}

}

12345678

Threads

T0

T1

Line4 Line5 Line6getInstance

getInstance

Time Line

Line4 Line5 Line6

Page 8: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Usedouble-checkedlocktomakeitmoreefficient• Motivation:Intheearlydays,thecostofsynchronizationcouldbequitehigh• Idea:Avoidthecostlysynchronizationforallinvocationsofthemethodexceptthefirst• Solution:• Firstcheckiftheinstanceisnullornot• Ifinstanceisnull,enteracriticalsectiontocreatetheobject• Ifinstanceisnotnull,returninstance

3/26/19 8

Page 9: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Doublechecked-lockimplementation

3/26/19 9

public class Instance {private static Instance instance;public static Instance getInstance() {if (instance == null) {synchronized (Instance.class) {if (instance == null) {

instance = new Instance();}

}}return instance;

}}

12345678910111213

Page 10: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Howdouble-checkedlockgoeswrong• Briefanswer:instructionreorder• SupposeT0isinitializingwiththefollowingthreesteps1) mem=allocate();//AllocatememoryforSingleton2) ctorSingleton(mem);//Invokeconstructor3) object.instance =mem;//initializeinstance.

• Whatifstep2isinterchangedwithstep3?• AnotherthreadT1mightseetheinstancebeforebeingfullyconstructed

3/26/19 10

Page 11: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Athreadreturnsanobjectthathasnotbeenconstructed

3/26/19 11

public static Instance getInstance() {if (instance == null) {synchronized (UnsafeInstance.class) {if (instance == null) {

instance = new Instance();}

}}return instance;

}

3456789101112

Threads

T0

T1

Line4

Line4

Line5

Line11

Line6getInstance

getInstance

Time Line

Line7

mem = allocate();object.instance = mem;ctorSingleton(mem);

T1returnsbeforeconstructorcompletes!

Page 12: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Usevolatiletoavoidreordering

• Thebehaviorofvolatile differssignificantlybetweenprogramminglanguages• C/C++

• Volatilekeywordmeansalwaysreadthevalueofthevariablememory

• Operationsonvolatilevariablesarenotatomic• Cannotbeusedasaportablesynchronizationmechanism

• Java• Preventreordering• DeriveasynchronizationorderontopofJavaMemoryModel

3/26/19 12

Page 13: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Usevolatiletoavoidreordering

• Java’svolatile wasnotconsistentwithdevelopersintuitions• TheoriginalJavamemorymodelallowedforvolatilewritestobereorderedwithnonvolatilereadsandwrites

• UnderthenewJavamemorymodel(fromJVMv1.5),volatilecanbeusedtofixtheproblemswithdouble-checkedlocking

3/26/19 13

Page 14: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Javamemorymodelhistory

• 1996:AnOptimizationPatternforEfficientlyInitializingandAccessingThread-safeObjects,DouglasC.Schmidt andetc.• 1996:TheJavaLanguageSpecification,chapter17,JamesGoslingandetc.• 1999:FixingtheJavaMemoryModel,WilliamPugh• 2004:JSR133---JavaMemoryModelandThreadSpecificationRevision

3/26/19 14

Page 15: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Review:sequentialconsistency

• Totalorder:Memoryactionsmustappeartoexecuteoneatatimeinasingletotalorder• Programorder:Actionsofagiventhreadmustappearinthesameorderinwhichtheyappearintheprogram

3/26/19 15

Page 16: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Review:sequentialconsistencyviolation

3/26/19 16

r2=xy=1

r1=yx=2

Thread1 Thread2

Initialconditions:x=y=0

Finalresults: r2==2andr1==1?

Decision:Disallowed.Violatessequentialconsistency

12

34

Circulardependency!

Interthreadsdependency

Intrathreaddependency

Page 17: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Javamemorymodelbalancesbetweenperformanceandsafety• Sequentialconsistency• Easytounderstand• Restrictstheuseofmanycompilerandhardwaretransformations

• Relaxedmemorymodels• Allowmoreoptimizations• Hardtoreasonaboutthecorrectness

3/26/19 17

Page 18: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Javamemorymodelhidesunderlyinghardwarememorymodel

3/26/19 18

JavaProgram

High-levelLanguageMemoryModel

JavaCompiler

JavaRuntime

HardwareMemoryModel

TSO, Power’s weak model, …

Page 19: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Javadefinesdata-race-freemodel

• Dataraceoccurswhentwothreadsaccessthesamememorylocation,atleastoneoftheaccessesisawrite,andthereisnointerveningsynchronization• Adata-race-free Javaprogramguaranteessequentialconsistency(Correctlysynchronized)

3/26/19 19

Page 20: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Anotherdefinitionofdata-racefromJavaMemoryModel’sperspective• Twoaccessesx andy formadataraceinanexecutionofaprogramiftheyarefromdifferentthreads,theyconflict,andtheyarenotorderedbyhappens-before

3/26/19 20

Page 21: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Happens-beforememorymodel

• AsimplerversionthanthefullJavaMemoryModel• Happens-beforeorder

• Thetransitiveclosureofprogramorderandthesynchronizes-withorder

• Happens-beforeconsistency• Determinesthevaluethatanon-volatilereadcansee

• Synchronizationorderconsistency• Determinesthevaluethatavolatilereadcansee

• SolvespartoftheJavamysteriousproblems

3/26/19 21

Page 22: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Programorderdefinition

• TheprogramorderofthreadT isatotalorderthatreflectstheorderinwhichtheseactionswouldbeperformedaccordingtointra-threadsemanticsofT• Ifx andy areactionsofthesamethreadandx comesbeforey inprogramorder,thenhb(x,y)(i.e.x happens-beforey)

3/26/19 22

Page 23: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Eliminateambiguityinprogramorderdefinition• GivenaprograminJava

• Programorderdoesnotmeanthaty=6mustbesubsequenttox=5fromawallclockperspective.Itonlymeansthatthesequenceofactionsexecutedmustbeconsistent withthatorder

3/26/19 23

y=6x=5

12

Page 24: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Whatshouldbeconsistentinprogramorder• Happens-beforeconsistency

• Areadr ofavariablev isallowedtoobserveawritew tov if• r doesnothappen-beforew (i.e.,itisnotthecasethathb(r,w))– areadcannotseeawritethathappens-afterit,and

• Thereisnointerveningwritew0 tov(i.e.,nowritew0 tov suchthathb(w,w0),hb(w0,r))–thewritew isnotoverwrittenalongahappens-beforepath.

• GivenaJavaprogram

• hb(1,2)&hb(2,3)->hb(1,3),soz sees6bewrittentoy

3/26/19 24

y=6x=5z=y

123

Page 25: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

SynchronizationOrder

• Asynchronizationorderisatotalorderoverallofthesynchronizationactionsofanexecution• Awritetoavolatilevariablev synchronizes-with allsubsequentreadsofv byanythread;• Anunlockactiononmonitorm synchronizes-with allsubsequentlockactionsonm thatwereperformedbyanythread;• …

• Ifanactionx synchronizes-with afollowingactiony,thenwehavehb(x,y)

3/26/19 25

Page 26: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Whatshouldbeconsistentinsynchronizationorder• Synchronizationorderconsistency• Synchronizationorderisconsistentwithprogramorder• Eachreadr ofavolatilevariablev seesthelastwritetovtocomebeforeitinthesynchronizationorder

3/26/19 26

Page 27: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Happens-beforememorymodelexample

3/26/19 27

x=1ready=true

if (ready)r1=x

Thread1 Thread2

12

34

synchronization-with

programorder

Initialconditions:x=0,ready=false,readyisvolatile

Finalresults: r1==1?

Decision:Allowed.Theprogramiscorrectlysynchronized

Proof:Programorder:hb(L1,L2)and hb(L3,L4)Synchronizationorder:hb(L2,L3)Transitive:hb(L1,L4)

Recall data-race definition:Two accesses x and y form adata race in an execution of aprogram if they are fromdifferent threads, they conflict,and they are not ordered byhappens-before

Page 28: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Correctdouble-checkedlockwithvolatile

3/26/19 28

public class Instance {private volatile static Instance instance;public static Instance getInstance() {if (instance == null) {synchronized (Instance.class) {if (instance == null) {

instance = new Instance();}

}}return instance;

}}

12345678910111213

1. mem = allocate();2. ctorSingleton(mem);3. object.instance = mem;

hb(2,3)ensuresthatL2’swritetomemcanbeseenatL3

Page 29: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Happens-beforedoesn’tsolveallproblems

3/26/19 29

r1=xif (r1!= 0)y=42

r2=yif (r2!= 0)x=42

Thread1 Thread2

Initialconditions:x=y=0

Finalresults: r1==r2==42?

Decision:Disallowed.Becausethevaluesareout-of-thin-air.

Inafutureaggressivesystem,Thread1couldspeculativelywritethevalue42toy.Howtoproposeamethodologytodisallowthesebehaviors?

123

456

Page 30: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Happens-beforedoesn’tsolveallproblems

3/26/19 30

r1=ar2=aif(r1==r2)b=2

r3=ba=r3

Thread1 Thread2

Initialconditions:a=0,b=1

Finalresults: r1==r2==r3==2?

Decision:Allowed.Acompilermaydeterminesthatr1 andr2 havethesamevalueandeliminateif r1==r2 (L3).Then,b=2(L4) canbemovedtoanearlierposition(L1)

1234

56

b=2r1=ar2=r1if (true)

r3=ba=r3

Thread1 Thread2

1234

45

Page 31: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

What’sthedifferencebetweentwoprograms• Onedifferencebetweentheacceptableandunacceptableresultsisthatinlatterprogram,thewritethatweperform(i.e.b=2)wouldalsohaveoccurredifwehadcarriedontheexecutioninasequentiallyconsistentway.• Intheformerprogram,value42inanysequentiallyconsistentexecutionwillnotbewritten.

3/26/19 31

Page 32: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Well-behavedexecution

• Wedistinguishtwoprogramsbyconsideringwhetherthosewritescouldoccurinasequentiallyconsistentexecution.• Well-behavedexecution• Areadthatmustreturnthevalueofawritethatisorderedbeforeitbyhappens-before.

3/26/19 32

Page 33: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Disallowedexamples-datadependency

3/26/19 33

r1=xa[r1]=0r2=a[0]y=r2

r3=yx=r3

Thread1 Thread2

1234

56

Initialconditions:x=y=0;a[0]=1,a[1]=2

Finalresults: r1==r2==r3==1?

Decision:Disallowed.Becausevaluesareout-of-thin-air.

Proof:Wehavehb(L1,L2),hb(L2,L3).Toletr2==1,a[0]mustbe0.Sinceinitiallya[0]==1andhb(L2,L3),wehaver1==0ata[r1]=0(L2).r1 atL2 isthefinalvalueBecausehb(L1,L2),r1 atL2mustseethewritetor1 atr1=x (L1).

Page 34: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Disallowedexamples-controldependency

3/26/19 34

z=1 r1=zif (r1== 0)x=1

Thread1 Thread2

1 234

r2=xy=r2

Thread3

r3=yx=r3

Thread456

78

Initialconditions:x=y=z=0

Finalresults: r1==r2==r3==1?

Decision:Disallowed.Becausevaluesareout-of-thin-air.

Proof:Becausewehavehb(L5,L6),toletr2==1(sothaty=1),x=1 (L4)mustbeexecuted.IfL4 isexecuted,if (r1==0) (L3)mustbetrue.However,sincer1 ==1 andhb(L2,L3),L4 cannotbeexecuted.

Page 35: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Disallowedexamples-controldependency

3/26/19 35

r1=xif (r1== 0)x=1

Thread1123

r2=xy=r2

Thread2

r3=yx=r3

Thread345

67

Initialconditions:x=y=0

Finalresults: r1==r2==r3==1?

Decision:Disallowed.Becausevaluesareout-of-thin-air

Proof:Thesamereasonasthepreviousexample.

Page 36: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Causality

• Actionsthatarecommittedearliermaycauseactionsthatarecommittedlatertooccur• Thebehaviorofincorrectlysynchronizedprogramsisboundedbycausality• ThecausalityrequirementisstrongenoughtorespectthesafetyandsecuritypropertiesofJavaandweakenoughtoallowstandardcompilerandhardwareoptimizations

3/26/19 36

Page 37: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Justifyacorrectexecution

• Buildupcausalityconstraintstojustify executions• Ensuresthattheoccurrenceofacommittedactionanditsvaluedoesnotdependonanuncommitteddatarace

• Justificationsteps• StartingwiththeemptysetasC0• PerformasequenceofstepswherewetakeactionsfromthesetofactionsA andaddthemtoasetofcommittedactionsCi togetanewsetofcommittedactionsCi+1• Todemonstratethatthisisreasonable,foreachCi weneedtodemonstrateanexecutionE containingCi thatmeetscertainconditions

3/26/19 37

Page 38: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Justificationexamples-reorder

3/26/19 38

r1=xy=1

r2=yx=r2

Thread1 Thread2

Initialconditions:x=y=0

Finalresults: r1==r2==1?

Decision:Allowed,becauseofcompilertransformation.y=1(L2) isaconstantthatdoesnotaffectr1=x(L2).

12

34

y=1r1=x

r2=yx=r2

Thread1 Thread212

34

C1:y=1r2=y(0)x=r2(0)r1=x(0)

C2:y=1r2=y(1)x=r2(1)r1=x(0)

C3:y=1r2=y(1)x=r2(1)r1=x(0)

C4:y=1r2=y(1)x=r2(1)r1=x(1)

Page 39: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Justificationexamples-redundantelimination

3/26/19 39

r1=aif (r1==1)b=1

r2=bif(r2==1)a=1

if(r2==0)a=1

Thread1 Thread2

123

45678Initialconditions:a=b=0

Finalresults: r1==r2==1?

Decision:Allowed.Acompiler coulddeterminethatThread2alwayswrites1 toa andhoiststhewritetothebeginningofThread2.

C1:a=1r1=a(0)b=1(0)r2=b(0)

C2:a=1r1=a(1)b=1(0)r2=b(0)

C3:y=1r1=a(1)b=1(1)r2=b(0)

C4:y=1r1=a(1)b=1(1)r2=b(1)

r1=aif (r1==1)b=1

a=1r2=b

Thread1 Thread2

123

45

Page 40: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Justificationexamples-interthreadanalysis

3/26/19 40

r1=xr2=1+r1*r1– r1y=r2

r3=yx=r3

Thread1 Thread2

123

45

Initialconditions:x=y=0

Finalresults: r1==r2==1?

Decision:Allowed.Interthreadanalysiscoulddeterminethatx andy arealwayseither0 or1,andthusdeterminethatr2 isalways1.Oncethisdeterminationismade,thewriteof1 toy couldbemovedearlyinThread1.

r2=1y=r2r1=x

r3=yx=r3

Thread1 Thread2

123

45

C1:r2=1y=r2(0)r3=y(0)x=r3(0)r1=x(0)

C2:r2=1y=r2(1)r3=y(0)x=r3(0)r1=x(0)

C3:r2=1y=r2(1)r3=y(1)x=r3(0)r1=x(0)

C4:r2=1y=r2(1)r3=y(1)x=r3(1)r1=x(0)

C5:r2=1y=r2(1)r3=y(1)x=r3(1)r1=x(1)

Page 41: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Comparisonbetweenallowedexamplesanddisallowedexamples

3/26/19 41

r1=xif (r1== 0)x=1

Thread1123

r2=xy=r2

Thread2

r3=yx=r3

Thread345

67

r1=xif (r1== 0)x=1

r2=xy=r2

Thread112345

r3=yx=r3

Thread267

Initialconditions:x=y=0

Finalresults: r1==r2==r3 == 1?

Decision:Allowed.Interthreadanalysiscoulddeterminethatx isalways0or1.Sowecanreplacer2=xbyr2=1 andy=r2 byy=1.Aftermovingy=1 andr2=1 toanearlierposition,wegetr1==r2==r3.

y=1r2=1r1=xif (r1== 0)x=1

Thread1

r3=yx=r3

Thread267

12345

Page 42: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Comparisonbetweenallowedexamplesanddisallowedexamples

3/26/19 42

r1=xif (r1== 0)x=1

Thread1123

r2=xy=r2

Thread2

r3=yx=r3

Thread345

67

Initialconditions:a=b=0

Finalresults: r1==r2==r3 == 2?

Decision:Allowed.AlthoughtherearesomeSCexecutionsinwhichr1!=r2(L3),wecanhoistb=2 (L4)toanearlierpositionandthereisanSCexecutionsuchthatr1==r2.Fortheabovecase,there’snoSCexecutionsuchthatr1==0 (L2)istrue andr1==r2==r3==1.Thatis,ifwehoistx=1 toanearlierposition,L2mustbefalse.

r1=ar2=aif(r1==r2)b=2

r3=ba=r3

Thread1 Thread2

1234

12

123

12

Page 43: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Practicalissues-finalfield

• “Forspacereasons,weomitdiscussionoftwoimportantissuesintheJavamemorymodel:thetreatmentoffinalfields,andfinalization/garbagecollection.”• Java’sfinal fieldalsoallowsprogrammerstoimplementthread-safeimmutableobjectswithoutsynchronization

3/26/19 43

Page 44: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Ruleofthumb

• Setthefinalfieldsforanobjectinthatobject'sconstructor;anddonotwriteareferencetotheobjectbeingconstructedinaplacewhereanotherthreadcanseeitbeforetheobject'sconstructorisfinished.• Whathappensintheconstructor• Ifareadoccursafterthefieldissetintheconstructor,itseesthevaluethefinalfieldisassigned,otherwiseitseesthedefaultvalue.

3/26/19 44

Page 45: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Canwechangeafinalfield?

• Reflectionintroducesproblems• Thespecificationallowsaggressiveoptimizationoffinalfields.Withinathread,itispermissibletoreorderreadsofafinalfieldwiththosemodificationsofafinalfieldthatdonottakeplaceintheconstructor.

3/26/19 45

Page 46: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Practicalissues-finalfield

3/26/19 46

• new A().f()couldreturn-1,0,or1class A {final int x;A() { x = 1; }int f() { return d(this,this); }int d(A a1, A a2) {int i = a1.x;g(a1);int j = a2.x;return j - i;

}static void g(A a) {

// uses reflection to change a.x to 2}

}

1234567891011121314

reorder!

Page 47: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Practicalissues-finalfield

3/26/19 47

• new A().f()couldreturn-1,0,or1class A {final int x;A() { x = 1; }int f() { return d(this,this); }int d(A a1, A a2) {int i = a1.x;g(a1);int j = a2.x;return j - i;

}static void g(A a) {

// uses reflection to change a.x to 2}

}

1234567891011121314

return1

Page 48: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Practicalissues-finalfield

3/26/19 48

• new A().f()couldreturn-1,0,or1class A {final int x;A() { x = 1; }int f() { return d(this,this); }int d(A a1, A a2) {g(a1);int i = a1.x;int j = a2.x;return j - i;

}static void g(A a) {// uses reflection to change a.x to 2

}}

1234567891011121314

return0

Page 49: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Practicalissues-finalfield

3/26/19 49

• new A().f()couldreturn-1,0,or1class A {final int x;A() { x = 1; }int f() { return d(this,this); }int d(A a1, A a2) {int j = a2.x;g(a1);int i = a1.x;return j - i;

}static void g(A a) {// uses reflection to change a.x to 2

}}

1234567891011121314

return-1

Page 50: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Practicalissue-efficientsingleton

• Theinitialization-on-demandholder(designpattern)idiomisalazy-loadedsingleton.InallversionsofJava,theidiomenablesasafe,highlyconcurrentlazyinitializationwithgoodperformance.

3/26/19 50

public class SafeInstance {private SafeInstance() {}private static class LazyHolder {static final SafeInstance INSTANCE = new SafeInstance();

}public static SafeInstance getInstance() {return LazyHolder.INSTANCE;

}}

123456789

Page 51: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Whyinitialization-on-demandholderissafe?• Whentheclassisinitialized?• AclassorinterfacetypeTwillbeinitializedimmediatelybeforethefirstoccurrenceofanyoneofthefollowing:• AstaticfielddeclaredbyTisusedandthefieldisnotaconstantvariable• AvariableofprimitivetypeortypeString,thatisfinalandinitializedwithacompile-timeconstantexpressioniscalledaconstantvariable.

• …

3/26/19 51

Page 52: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Whyinitialization-on-demandholderissafe?• Whyinitializationissafe?• ForeachclassorinterfaceC,thereisauniqueinitializationlockLC.ThemappingfromC toLC islefttothediscretionoftheJavaVirtualMachineimplementation.• WecanalsoimplementsingletonbyENUMinJava.

3/26/19 52

Page 53: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

Conclusion

• Followinghappens-beforerulesallowsustowriteadata-race-freeprogramthatiscorrectlysynchronized.• Javamemorymodelprovidesacleardefinitionofwell-behavedexecutions,preventingvaluescomeout-of-thin-airinthepresenceofdatarace.• Double-checkedlockisthread-safeforJVMlaterthanv1.5.

3/26/19 53

Page 54: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

ReferenceBooks

• Goetz,Brian,etal.Javaconcurrencyinpractice.PearsonEducation,2006.• Gosling,James,etal.TheJavalanguagespecification.PearsonEducation,2014.• Lea,Doug."TheJSR-133cookbookforcompilerwriters."(2008).

3/26/19 54

Page 55: The Java Memory Model - Rice Universityjohnmc/comp522/lecture-notes/COMP522-… · Use volatile to avoid reordering •The behavior of volatilediffers significantly between programming

ReferenceURLs

• Double-checkedlockinghttps://www.ibm.com/developerworks/java/library/j-dcl/index.html• Causalitytestcaseshttp://www.cs.umd.edu/~pugh/java/memoryModel/unifiedProposal/testcases.html

3/26/19 55