Josh Bloch Charlie Garrod Darya Melichercharlie/courses/17-214/2018-fall/slides/... · 17-214 2...
Transcript of Josh Bloch Charlie Garrod Darya Melichercharlie/courses/17-214/2018-fall/slides/... · 17-214 2...
1 17-214
PrinciplesofSo3wareConstruc9on: Objects,Design,andConcurrencyPart42:ConcurrencyIntroduc9ontoconcurrencyJoshBlochCharlieGarrodDaryaMelicher
2 17-214
Administrivia
• Homework5teamsign-updeadlinetonight• Teamsizes,presenta9onslots,…
– MidtermexaminclassThursday(November1st)• Reviewsessiontoday7-9p.m.PorterHall100
– NextrequiredreadingdueTuesday• JavaConcurrencyinPrac9ce,Sec9ons11.3and11.4
– Homework5frameworksdiscussion
3 17-214
Today
• Somepuzzlers• APIdesignconclusions• Introduc9ontoconcurrency
4 17-214
1.“TimeforaChange” (2002)
Ifyoupay$2.00foragasketthatcosts$1.10,howmuchchangedoyouget? publicclassChange{publicstaticvoidmain(Stringargs[]){System.out.println(2.00-1.10);}}
From An Evening Of Puzzlers by Josh Bloch
5 17-214
Whatdoesitprint?
(a) 0.9 (b) 0.90 (c) It varies (d) None of the above
publicclassChange{publicstaticvoidmain(Stringargs[]){System.out.println(2.00-1.10);}}
6 17-214
(a)0.9(b)0.90(c)Itvaries(d)Noneoftheabove:0.8999999999999999 Decimalvaluescan'tberepresentedexactlyby float or double
Whatdoesitprint?
7 17-214
Anotherlook
publicclassChange{publicstaticvoidmain(Stringargs[]){System.out.println(2.00-1.10);}}
8 17-214
Howdoyoufixit?
//Youcouldfixitthisway...importjava.math.BigDecimal;publicclassChange{publicstaticvoidmain(Stringargs[]){System.out.println(newBigDecimal("2.00").subtract(newBigDecimal("1.10")));}}
//...oryoucouldfixitthiswaypublicclassChange{publicstaticvoidmain(Stringargs[]){System.out.println(200-110);}}
Prints0.90
Prints90
9 17-214
Themoral
• Avoid float and doublewhereexactanswersarerequired– Forexample,whendealingwithmoney
• UseBigDecimal,int,orlonginstead
10 17-214
2.“AChangeisGonnaCome”
Ifyoupay$2.00foragasketthatcosts$1.10,howmuchchangedoyouget? importjava.math.BigDecimal;publicclassChange{publicstaticvoidmain(Stringargs[]){BigDecimalpayment=newBigDecimal(2.00);BigDecimalcost=newBigDecimal(1.10);System.out.println(payment.subtract(cost));}}
11 17-214
Whatdoesitprint?
importjava.math.BigDecimal;publicclassChange{publicstaticvoidmain(Stringargs[]){BigDecimalpayment=newBigDecimal(2.00);BigDecimalcost=newBigDecimal(1.10);System.out.println(payment.subtract(cost));}}
(a)0.9(b)0.90(c)0.8999999999999999(d)None of the above
12 17-214
(a)0.9(b)0.90(c)0.8999999999999999(d)Noneoftheabove:0.899999999999999911182158029987476766109466552734375
WeusedthewrongBigDecimalconstructor
Whatdoesitprint?
13 17-214
Anotherlook
importjava.math.BigDecimal;publicclassChange{publicstaticvoidmain(Stringargs[]){BigDecimalpayment=newBigDecimal(2.00);BigDecimalcost=newBigDecimal(1.10);System.out.println(payment.subtract(cost));}}
Thespecsays: publicBigDecimal(doubleval)TranslatesadoubleintoaBigDecimalwhichistheexactdecimalrepresenta9onofthedouble'sbinaryfloa9ng-pointvalue.
14 17-214
Howdoyoufixit?
importjava.math.BigDecimal;publicclassChange{publicstaticvoidmain(Stringargs[]){BigDecimalpayment=newBigDecimal("2.00");BigDecimalcost=newBigDecimal("1.10");System.out.println(payment.subtract(cost));}}
Prints0.90
15 17-214
The moral
• Use newBigDecimal(String), not newBigDecimal(double)
• BigDecimal.valueOf(double) is better, but not perfect – Use it for non-constant values.
• For API designers – Make it easy to do the commonly correct thing – Make it hard to misuse – Make it possible to do exotic things
16 17-214
KeyconceptsfromlastThursday
17 17-214
Keydesignprinciple:Informa9onhiding
• "Whenindoubt,leaveitout."
18 17-214
Minimizemutability
• Classesshouldbeimmutableunlessthere'sagoodreasontodootherwise– Advantages:simple,thread-safe,reusable
• Seejava.lang.String– Disadvantage:separateobjectforeachvalue
• Mutableobjectsrequirecarefulmanagementofvisibilityandsideeffects– e.g.Component.getSize()returnsamutableDimension
• Documentmutability– Carefullydescribestatespace
19 17-214
Failfast
• Reporterrorsassoonastheyaredetectable– Checkprecondi9onsatthebeginningofeachmethod– Avoiddynamictypecasts,run-9metype-checking
//APropertiesinstancemapsStringstoStringspublicclassPropertiesextendsHashTable{publicObjectput(Objectkey,Objectvalue);//ThrowsClassCastExceptionifthisinstance//containsanykeysorvaluesthatarenotStringspublicvoidsave(OutputStreamout,Stringcomments);}
20 17-214
Subtle9esofinforma9onhiding
• Preventsubtleleaksofimplementa9ondetails– Documenta9on– Lackofdocumenta9on– Implementa9on-specificreturntypes– Implementa9on-specificexcep9ons– Outputformats– implementsSerializable
21 17-214
Avoidbehaviorthatdemandsspecialprocessing
• Donotreturnnulltoindicateanemptyvalue– e.g.,UseanemptyCollectionorarrayinstead
• Donotreturnnulltoindicateanerror– Useanexcep9oninstead
22 17-214
Throwexcep9onsonlyforexcep9onalbehavior
• Donotforceclienttouseexcep9onsforcontrolflow:privatebyte[]a=newbyte[CHUNK_SIZE];voidprocessBuffer(ByteBufferbuffer){try{while(true){buffer.get(a);…}}catch(BufferUnderflowExceptione){intremaining=buffer.remaining();buffer.get(a,0,remaining);…}}
• Conversely,don’tfailsilently:ThreadGroup.enumerate(Thread[]list)
23 17-214
Context:Theexcep9onhierarchyinJava
Throwable
Exception
RuntimeException IOException
EOFException
FileNotFoundException
NullPointerException
IndexOutOfBoundsException
ClassNotFoundException… …
. . .
Object
unchecked checked
24 17-214
Avoidcheckedexcep9ons,ifpossible
• Overuseofcheckedexcep9onscausesboilerplatecode:try{
Foof=(Foo)g.clone();}catch(CloneNotSupportedExceptione){//Thisexceptioncan'thappenifFooisCloneablethrownewAssertionError(e);}
25 17-214
Don'tletyouroutputbecomeyourdefactoAPI
• Documentthefactthatoutputformatsmayevolveinthefuture• Provideprogramma9caccesstoalldataavailableinstringform
26 17-214
Don'tletyouroutputbecomeyourdefactoAPI
• Documentthefactthatoutputformatsmayevolveinthefuture• Provideprogramma9caccesstoalldataavailableinstringform
publicclassThrowable{publicvoidprintStackTrace(PrintStreams);publicStackTraceElement[]getStackTrace();//since1.4}publicfinalclassStackTraceElement{publicStringgetFileName();publicintgetLineNumber();publicStringgetClassName();publicStringgetMethodName();publicbooleanisNativeMethod();}
27 17-214
APIdesignsummary
• Acceptthefactthatyou,andothers,willmakemistakes– UseyourAPIasyoudesignit– Getfeedbackfromothers– Hideinforma9ontogiveyourselfmaximumflexibilitylater– Designforinaien9ve,hurriedusers– Documentreligiously
• Ittakesalotofworktomakesomethingthatappearsobvious
28 17-214
Semesteroverview
• Introduc9ontoJavaandO-O• Introduc9ontodesign
– Designgoals,principles,paierns• Designingclasses
– Designforchange– Designforreuse
• Designing(sub)systems– Designforrobustness– Designforchange(cont.)
• Designcasestudies• Designforlarge-scalereuse• Explicitconcurrency
• Crosscukngtopics:– Moderndevelopmenttools:
IDEs,versioncontrol,buildautoma9on,con9nuousintegra9on,sta9canalysis
– Modelingandspecifica9on,formalandinformal
– Func9onalcorrectness:Tes9ng,sta9canalysis,verifica9on
29 17-214
Concurrency,mo9va9onandprimi9ves
• Thebackstory– Mo9va9on,goals,problems,…
• Concurrencyprimi9vesinJava• Comingsoon(nottoday):
– Higher-levelabstrac9onsforconcurrency– Programstructureforconcurrency– Frameworksforconcurrentcomputa9on
30 17-214
PowerrequirementsofaCPU
• Approx.:Capacitance*Voltage2*Frequency• Toincreaseperformance:
– Moretransistors,thinnerwires• Morepowerleakage:increaseV
– IncreaseclockfrequencyF• Changeelectricalstatefaster:increaseV
• Dennardscaling:Astransistorsgetsmaller,powerdensityisapproximatelyconstant…– …un9learly2000s
• Heatoutputispropor9onaltopowerinput
31 17-214
Oneop9on:fixthesymptom
• Dissipatetheheat
32 17-214
Oneop9on:fixthesymptom
• Beier:Dissipatetheheatwithliquidnitrogen– OverclockingbyTom'sHardware's5GHzproject
http://www.tomshardware.com/reviews/5-ghz-project,731-8.html
33 17-214
Processorcharacteris9csover9me
34 17-214
Concurrencythenandnow
• Inthepast,mul9-threadingjustaconvenientabstrac9on– GUIdesign:eventdispatchthread– Serverdesign:isolateeachclient'swork– Workflowdesign:isolateproducersandconsumers
• Now:requiredforscalabilityandperformance
35 17-214
Weareallconcurrentprogrammers
• Javaisinherentlymul9threaded• Tou9lizemodernprocessors,wemustwritemul9threadedcode• Goodnews:alotofitiswriienforyou
– Excellentlibrariesexist(java.util.concurrent)• Badnews:yous9llmustunderstandfundamentals
– …touselibrarieseffec9vely– …todebugprogramsthatmakeuseofthem
36 17-214
Aside:Concurrencyvs.parallelism,visualized
• Concurrencywithoutparallelism:
• Concurrencywithparallelism:
37 17-214
BasicconcurrencyinJava
• Aninterfacerepresen9ngataskpublicinterfaceRunnable{voidrun();}
• AclasstoexecuteataskinathreadpublicclassThread{publicThread(Runnabletask);publicvoidstart();publicvoidjoin();…}
38 17-214
Example:Money-grab(1)
publicclassBankAccount{privatelongbalance;publicBankAccount(longbalance){this.balance=balance;}staticvoidtransferFrom(BankAccountsource,BankAccountdest,longamount){source.balance-=amount;dest.balance+=amount;}publiclongbalance(){returnbalance;}}
39 17-214
Example:Money-grab(2)publicstaticvoidmain(String[]args)throwsInterruptedException
{BankAccountbugs=newBankAccount(100);BankAccountdaffy=newBankAccount(100);ThreadbugsThread=newThread(()->{for(inti=0;i<1_000_000;i++)transferFrom(daffy,bugs,100);});ThreaddaffyThread=newThread(()->{for(inti=0;i<1_000_000;i++)transferFrom(bugs,daffy,100);});bugsThread.start();daffyThread.start();bugsThread.join();daffyThread.join();System.out.println(bugs.balance()+daffy.balance());}
40 17-214
Whatwentwrong?
• Daffy&Bugsthreadshadaracecondi.onforshareddata– Transfersdidnothappeninsequence
• Readsandwritesinterleavedrandomly– Randomresultsensued
41 17-214
Thechallengeofconcurrencycontrol
• Notenoughconcurrencycontrol:safetyfailure– Incorrectcomputa9on
• Toomuchconcurrencycontrol:livenessfailure– Possiblynocomputa9onatall(deadlockorlivelock)
42 17-214
Sharedmutablestaterequiresconcurrencycontrol
• Threebasicchoices:1. Don'tmutate:shareonlyimmutablestate2. Don'tshare:isolatemutablestateinindividualthreads3. Ifyoumustsharemutablestate:limitconcurrencytoachievesafety
43 17-214
Aneasyfix:
publicclassBankAccount{privatelongbalance;publicBankAccount(longbalance){this.balance=balance;}staticsynchronizedvoidtransferFrom(BankAccountsource,BankAccountdest,longamount){source.balance-=amount;dest.balance+=amount;}publicsynchronizedlongbalance(){returnbalance;}}
44 17-214
ConcurrencycontrolwithJava'sintrinsiclocks
• synchronized(foo){…}– Synchronizesen9reblockonobjectfoo;cannotforgettounlock– Intrinsiclocksareexclusive:Onethreadata9meholdsthelock– Intrinsiclocksarereentrant:Athreadcanrepeatedlygetsamelock
45 17-214
ConcurrencycontrolwithJava'sintrinsiclocks
• synchronized(foo){…}– Synchronizesen9reblockonobjectfoo;cannotforgettounlock– Intrinsiclocksareexclusive:Onethreadata9meholdsthelock– Intrinsiclocksarereentrant:Athreadcanrepeatedlygetsamelock
• synchronizedonaninstancemethod– Equivalenttosynchronized(this){…}foren9remethod
• synchronizedonasta9cmethodinclassFoo– Equivalenttosynchronized(Foo.class){…}foren9remethod
46 17-214
Summary
• Likeitornot,you’reaconcurrentprogrammer• Ideally,avoidsharedmutablestate
– Ifyoucan’tavoidit,synchronizeproperly