ListofListings
2.1Exampleofamethoddefinedwithasymbolicname.13
2.2Exampleofamethoddefinedforinfixinvocation. 13
2.3Exampleofamethodaddedtoatypebyextension. 14
2.4Exampleofalocalfunctiondefinedwithinanotherfunction. 14
2.5Exampleofafunctionwithvariable-lengtharguments. 15
2.6Exampleofafunctionwithdefaultvaluesforsomeofitsarguments. 16
2.7Exampleofafunctionparameterizedbyatype;contrastwithLis.2.8.18
2.8Exampleofparameterizationbymultipletypes;contrastwithLis.2.7.19
3.1Purefunctionversusimpurefunctionversusaction. 24
3.2Exampleof if-then-else asastatement;contrastwithLis.3.3. 25
3.3Exampleof if-then-else asanexpression;contrastwithLis.3.2. 26
3.4Adirectoryasamutableset;contrastwithLis.3.5. 33
3.5Adirectoryasanimmutableset;contrastwithLis.3.4. 34
3.6Exampleofamutabletype;contrastwithLis.3.7. 35
3.7Exampleofanimmutabletype;contrastwithLis.3.6. 35
4.1Object-orientedactive-passivesets,usingunderlyingmutablesets. 39
4.2Object-orientedactive-passivesets,usingunderlyingimmutablesets. 40
4.3Functionalactive–passivesets. 41
4.4Functional–object-orientedactive–passivesets. 43
5.1Exampleofpatternmatchingusedasa switch expression. 47
5.2Exampleofpatternmatchingwithguards. 48
5.3Exampleofpatternmatchingfortypetesting/casting. 48
5.4Exampleofpatternmatchingtoextracttupleelements. 49
5.5Exampleofpatternmatchingtoboth switch and extract
5.6Reimplementing head and tail usingpatternmatching. 51
5.7Reimplementing isEmpty usingpatternmatching. 52
5.8Booleanexpressionsasanalgebraicdatatype. 54
5.9RecursiveevaluationofBooleanexpressionsusingpatternmatching. 54
5.10Listzipperdefinitionandconstruction. 57
5.11Listzippergettingandsetting. 58
5.12Listzippernavigation. 58
5.13Conversionfromlistzippertolist. 59
5.14Exampleofanextractor(RGBvalues).
6.1Nestingfunctioncallsthroughrecursion.
6.2Recursiveimplementationof factorial;contrastwithLis.6.11.
6.3RecursivesolutiontotheTowerofHanoiproblem.
6.4Incorrectimplementationof last;fixedinLis.6.10.
6.5Incorrectmergesort;fixedinLis.7.18.
6.7Recursiveimplementationof size onbinarytrees.
6.8Recursiveimplementationof size on N -arytrees.
6.9Tailrecursiveimplementationofbinarysearchinasortedsequence.
6.10Correcttailrecursiveimplementationof last;fixedfromLis.6.4.
6.11Tailrecursiveimplementationof factorial;contrastwithLis.6.2.
7.1Simplelistlookup,usingtailrecursion;seealsoLis.7.2.
7.2Simplelistlookup,usingtailrecursionandpatternmatching.
7.3Listlength, not tailrecursive;contrastwithLis.7.4.
7.4Listlength,usingtailrecursion;contrastwithLis.7.3.
7.5Recursiveimplementationof drop onlists;seealsoLis.7.6.
7.7Implementationof getAt onlists,using drop.
7.8Recursiveimplementationof take;contrastwithListings7.21to7.23.84
7.9Recursiveimplementationoflistconcatenation. 86
7.10Appendingattheendofalistusingconcatenation. 86
7.11Recursiveimplementationoflistflattening.
7.12Recursiveimplementationoflistzipping.
7.13Recursiveimplementationoflistsplitting.
7.14Recursiveimplementationoflistgrouping.
7.15Linear,tailrecursiveimplementationoflistreversal.
7.16Listbuildingbyprependingandreversinginsteadofappending.
7.17Insertionsort.
7.18Merge-sort;fixedfromLis.6.5;seealsoLis.7.19.
7.19Alternativeimplementationofmerge-sort;seealsoLis.7.18.
7.20Quick-sortwithuser-definedsplitting;seealsoLis.10.1. 94
7.21Tailrecursiveimplementationof take;contrastwithLis.7.8.
7.22Buffer-basedimplementationof take;contrastwithLis.7.21.
7.23Loop-basedimplementationof take;contrastwithLis.7.22.
8.1Emptybinarysearchtree.
8.6Setconversiontobalancedbinarysearchtrees,improvedinLis.8.12.107
8.7Leftandrightrotationsonbinarysearchtrees. 109
8.8Rebalancingofbinarysearchtreesbyrotations. 110
8.9Keyinsertioninself-balancingbinarysearchtrees. 111
8.10Keydeletioninself-balancingbinarysearchtrees;seealsoLis.8.11. 111
8.11Keydeletioninself-balancingbinarysearchtrees;seealsoLis.8.10. 112
8.12Conversionfromsettobinarysearchtrees,improvedfromLis.8.6. 112
9.1Listlookupforaspecifictarget.
9.2Recursiveimplementationofhigher-orderfunction find
9.3Exampleofafunctionthatreturnsafunction;seealsoLis.9.4and9.5.117
9.4Exampleofhigher-orderfunctionsdefinedthroughcurrying. 118
9.5Exampleofhigher-orderfunctionsdefinedusinglambdaexpressions. 121
9.6Memoizationusingclosures;seealsoLis.12.2. 130
9.7Exampleofafunctionwritinginitsclosure.
10.1Quick-sort,using partition
find using dropWhile
10.3Using flatMap toimplement map and filter
10.5Exampleofusing flatMap inapipeline;seealsoLis.10.9. 143
10.6Exampleofiteration,recursion,andfoldforthesamecomputation. 146
10.7 sum, product, reverse,and filter implementedusingfold. 147
10.8Extendingbinarysearchtreeswith exists, foreach,and fold
10.9RewrittenpipelinefromLis.10.5using for-comprehension.
11.1Exampleofusing foreach withamutablestringbuilder. 160 11.2Exampleofnodeinsertioninageneraltree. 161
11.3Exampleofnoderemovalinageneraltree. 163
11.4Exampleofusing fold tocountnodesinageneraltree. 164
11.5Exampleofimplementing exists onageneraltree. 164
11.6Exampleofimplementing fold onageneraltree. 165
11.7Exampleofimplementing find onageneraltree. 168
11.8Navigationmethodsinatreezipper(1). 171
11.9Navigationmethodsinatreezipper(2). 171
12.1Reimplementing List.fill 175
12.2Memoizationuisngaby-nameargument,improvedfromLis.9.6. 176
12.3Controlabstractionexample:function timeOf 177
12.4Controlabstractionexample:function times. 178
12.5Controlabstractionexample: repeat-until 178
12.6TowerofHanoimovesasalist;contrastwithLis.12.7. 181
12.7TowerofHanoimovesasastream. 182
12.8Imperativeimplementationofthe 3n +1 sequence. 185
12.9Functionalimplementationofthe 3n +1 sequence. 186
12.10Recursiveimplementationofsubset-sum;seealsoLis.12.11. 191
12.11Allthesolutionstosubset-sum;contrastwithLis.12.10and12.12. 192
12.12Thesolutionstosubset-sumderivedlazily;contrastwithLis.12.11. 192
13.1Pipelineexamplewithnohandlingoffailures;contrastwithLis.13.2.201
13.2Pipelineexamplewithfailurehandling;contrastwithLis.13.1. 202
14.1Exampleofnon-optimizedtail-calls;contrastwithLis.14.3.
14.2Trampolinefortail-calloptimizationinScala.
14.3Optimizedtail-calls,usingatrampoline;contrastwithLis.14.1.
14.4Trampolinefortail-calloptimizationinJava. 208
14.5Optimizedtail-calls,usingatrampoline,Javavariant.
14.6Trampolineextendedwith map and flatMap 211
14.7Non-tailrecursive factorial,asatrampoline;seealsoLis.14.10. 212
14.8Non-tailrecursive size ontrees,asatrampoline;seealsoLis.14.10.212
14.9Non-tailrecursive hanoi,asatrampoline;seealsoLis.14.10. 212 14.10 For-yield ontrampolines;contrastwithLis.14.7to14.9.
15.1Exampleofadhocpolymorphism.
15.2Exampleofparametricpolymorphism.
15.3Exampleofsubtypepolymorphism;seealsoLis.15.4.
15.4Usingsubtypepolymorphismtoprocessaheterogeneouscollection.
15.5Exampleofauser-definedcovarianttype.
15.6Exampleofauser-definedcontravarianttype.
15.7Exampleofanuppertypeboundforuse-sitevariance.
15.8Exampleofalowertypeboundforuse-sitevariance.
15.9Exampleofatypeparameterwithbothlowerandupperbounds.
15.10Exampleofacombineduppertypebound;contrastwithLis.15.14.
15.11Usingtypeboundsonnon-varianttypesforincreasedflexibility.
15.12ExampleofastructuraltypeinScala.
15.13Exampleofpolymorphismthroughatypeclass.
15.14Exampleofcombiningtypeboundsandtypeclassesforflexibility.
15.15Anaveragingfunctionbasedonatypeclass.
17.1Exampleofamultithreadedprogram.
17.2Exampleofcreatingthreadsusinglambdaexpressions.
17.3Requestingthreadterminationusingavolatileflag.
17.4Waitingforthreadterminationwithoutatimeout;seealsoLis.17.5.266
17.5Waitingforthreadterminationwithatimeout. 266
18.1Multiplethreadsshareanintegerunsafely.
18.2Multiplethreadssharealistunsafely;fixedinLis.18.5.
18.3Usingan AtomicInteger togenerateuniquevalues.
18.4Exampleofnon-atomiccheck-then-act;fixedinLis.18.7.
18.5Multiplethreadssharealistsafely;fixedfromLis.18.2.
18.6Illustrationoflockreentrancy. 281
18.7Atomiccheck-then-actusinglocking;fixedfromLis.18.4. 282
19.1Exampleofthreadsfreelysharingimmutableobjects. 285 19.2Safelistthatencapsulatessynchronization;contrastwithLis.18.5. 287 19.3Exampleofclient-sidelocking. 289
19.4Safelistbasedonaprivatelock;contrastwithLis.19.2. 290 19.5Safelistbasedonanimmutablelist;contrastwithLis.19.2and19.4.291 19.6Safelistwithanimmutablelist/privatelock;contrastwithLis.19.5.293
20.1Thread-safequeue(singlepubliclock);seealsoLis.20.5and20.7. 298 20.2Batchinsertionsbyclient-sidelockingonaconcurrentqueue. 299 20.3Batchextractionbyclient-sidelockingonaconcurrentqueue. 300 20.4Batchextractionwithoutsynchronization;contrastwithLis.20.3. 300 20.5Thread-safequeue(singleprivatelock);seealsoLis.20.1and20.7. 301 20.6Batchprocessingfromqueuewithaprivatelock. 302 20.7Thread-safequeue(twoprivatelocks);seealsoLis.20.1and20.5. 303 20.8Batchprocessingfromaqueuewithasplitlock. 304
21.1Exampleconcurrencyfromathreadpool;contrastwithLis.17.1. 307 21.2Usingathreadpooltocreatethreadsandwaitfortheirtermination.309
21.3Aserverthatprocessesrequestssequentially;contrastwithLis.21.4.310 21.4Aserverthatprocessesrequestsconcurrently;contrastwithLis.21.3.310
21.5Exampleofscheduledexecutionusingatimerpool. 313
21.6Exampleofparallelevaluationofhigher-orderfunction map
22.1Threadsfromapoolshareasafelist.
316
321
22.2Waitingfortaskcompletionusingacountdownlatchsynchronizer. 325
22.3Deadlock-proneimplementationofabox;fixedinLis.22.4.
326
22.4Thread-safeboxwithalatch;fixedfromLis.22.3;seealsoLis.27.2.327
22.5Firstvariantformethod set fromLis.22.4.
22.6Secondvariantformethod set fromLis.22.4.
328
328
22.7Exampleofeventstiedandnottiedbyhappens-before;seeFig.22.4.332
22.8Possibleimplementationof get inLis.22.4and22.6. 334
23.1VariantofLis.18.7withatimeout. 337
23.2Exampleuseofaread-writelock. 338
23.3AddlatchestoLis.21.2forincreasedconcurrencyandprecisetiming.339
23.4ReplacetwolatchesfromLis.23.3withasinglebarrier. 340
23.5Simplelockimplementationusingasemaphore. 341
23.6Boundedqueuebasedontwosemaphores;seealsoLis.23.7and23.8.342
23.7Boundedqueuewithasinglecondition;seealsoLis.23.8. 343
23.8Boundedqueuebasedontwoconditions. 345
23.9Searchingfilesandstoringresultsasaproducer–consumerpattern. 353
24.1Parallelexecution:onenewthreadpertask. 356
24.2Parallelexecution:boundednumberofthreads. 358
24.3Parallelexecution:dedicatedthreadpool. 359
24.4Parallelexecution:sharedthreadpool. 360
24.5Parallelexecution:sharedthreadpoolwithabound.361
24.6Parallelexecution:parallelcollections.
24.7Extensibleparallelexecutionusingasinglecondition.
24.8Extensibleparallelexecutionusingtwoconditions.
24.9Extensibleparallelexecutionusingtwosemaphores.
25.1Value-producingtaskshandledasfutures.
25.2Aparallelserverwithparallelismwithinresponses;seealsoLis.26.8.373
25.3Dealingwithafuture’stimeoutandfailure.
25.4Possibleimplementationof Future.apply;seealsoLis.25.5and25.6.376
25.5Futurecreationfroma CompletableFuture promise.
25.6Futurecreationfroma FutureTask promise. 377
25.7Athread-safememoizationfunction,usingpromisesandfutures.
26.1Deadlock-proneparallelquick-sort;seealsoLis.26.5.
26.2Ad-fetchingexample;contrastwithLis.26.3,26.6,and26.7.
26.3Ad-fetchingexamplewithacallbackonafuture.
26.4Reimplementinghigher-orderfunction map onfutures.
26.5Non-blockingimplementationofparallelquick-sort.
26.6Ad-fetchingexamplewith map and foreach onfutures.
26.7Ad-fetchingexamplewith flatMap and foreach onfutures.
26.8Afullynon-blockingparallelserver.
CompletableFuturesintoonewithoutblocking.
27.1Conceptualimplementationofclass AtomicInteger inJava.
27.2Thread-safeboxwithalatchandnolock.
27.3Lock-freeimplementationofathread-safestack(Treiber’salgorithm).403
27.4Exampleofnon-blockingconcurencyusing ForkJoinPool.
27.5Exampleofnon-blockingconcurrencywithan async/await construct.406
27.6Exampleofnon-blockingconcurrencyusingKotlincoroutines.
27.7Exampleofnon-blockingconcurrencyusingactors.
27.8Exampleofastatemachineasanactorthatswitchesbehavior.
27.9Exampleofnon-blockingtransformationusingreactivestreams.
28.1Asequentialrunnerofstrategieswithtimeout.
28.2Aparallelrunnerofstrategiesbasedon invokeAny
CompletionService
28.4ExtendingScalafutureswith completeOnTimeout
28.7Earliest CompletableFuture thatsatisfiesacondition.
28.8Asynchronousrunnervariantbasedon CompletableFuture.
28.9Asynchronousrunnerwiththread-safecaching.
ForewordbyCayHorstmann
Inmybook ScalafortheImpatient,Iprovidearapid-fireintroductionintothemany featuresoftheScalalanguageandAPI.Ifyouneedtoknowhowaparticularfeature works,youwillfindaconciseexplanationandaminimalcodeexample(withrealcode, notfruitsoranimals).IassumethatthereaderisfamiliarwithJavaorasimilarobjectorientedprogramminglanguageandorganizethematerialtomaximizetheexperience andintuitionofsuchreaders.Infact,IwrotethebookbecauseIwasputoffbythe learningmaterialsatthetime,whichweredisdainfulofobject-orientedprogramming andbiasedtowardfunctionalprogrammingasthesuperiorparadigm.
Thatwasmorethanadecadeago.Nowadays,functionaltechniqueshavebecome muchmoremainstream,anditiswidelyrecognizedthattheobject-orientedandfunctionalparadigmscomplementeachother.Inthisbook,MichelCharpentierprovides anaccessibleintroductiontofunctionalandconcurrentprogramming.UnlikemyScala book,thematerialhereisorganizedaroundconceptsandtechniquesratherthanlanguagefeatures.Thoseconceptsaredevelopedquiteabitmoredeeplythantheywould beinabookthatisfocusedonaprogramminglanguage.Youwilllearnaboutnontrivial andeleganttechniquessuchaszippersandtrampolines.
ThisbookusesScala3formostofitsexamples,whichisagreatchoice.Theconcise andelegantScalasyntaxmakestheconceptsstandoutwithoutbeingobscuredbya thicketofnotation.Youwillparticularlynoticethatwhenthesameconceptisexpressed inScalaandinJava.Youdon’tneedtoknowanyScalatogetstarted,andonlyamodest partofScalaisusedinthecodeexamples.Again,thefocusofthebookisconcepts, notprogramminglanguageminutiae.Masteringtheseconceptswillmakeyouabetter programmerinanylanguage,evenifyouneverendupusingScalainyourcareer.
Iencourageyoutoactivelyworkwiththesampleprograms.Executethem,observe theirbehavior,andexperimentbymakingchanges.IsuggestthatyouuseaprogrammingenvironmentthatsupportsScalaworksheets,suchasVisualStudioCode,IntelliJ, ortheonlineScastieservice.Withaworksheet,turnaroundisquickandexploratory programmingisenjoyable.
Sevenoutofthe28chaptersarecompletecasestudiesthatillustratethematerial thatprecededthem.Theyarechosentobeinterestingwithoutbeingoverwhelming.I amsureyouwillprofitfromworkingthroughthemindetail.
Thebookisdividedintotwoparts.Thefirstpartcoversfunctionalprogramming withimmutabledata,algebraicdatatypes,recursion,higher-orderfunctions,andlazy evaluation.Evenifyouareatfirstunexcitedaboutreimplementinglistsandtrees,give itachance.Observethecontrastwithtraditionalmutabledatastructures,andyou willfindthejourneyrewarding.Thebookisblessedlyfreeofcomplexcategorytheory thatinmyopinion—evidentlysharedbytheauthor—requiresalargeamountofjargon beforeyieldingpaltrygains.
Thefocusofthesecondpartisconcurrentprogramming.Heretootheorganization alongconceptsratherthanlanguageandAPIfeaturesisrefreshing.Concurrentprogrammingisacomplexsubjectwithmanydistinctusecasesandnoobviouswayof teachingitwell.Michelhasbrokendownthematerialintoaninterestingandthoughtprovokingsequenceofchaptersthatisquitedifferentfromwhatyoumayhaveseen before.Aswiththefirstpart,theultimateaimisnottoteachyouaspecificsetofskills andtechniques,buttomakeyouthinkatahigherlevelaboutprogramdesign. Ienjoyedreadingandworkingthroughthisuniquebookandverymuchhopethat youwilltoo.
CayHorstmann Berlin,2022
Preface
Beforeyoustartreadingthisbook,itisimportanttothinkaboutthedistinctionbetween programming languages andprogramminglanguage features.Ibelievethatdevelopers benefitfrombeingabletorelyonanextensivesetofprogramminglanguagefeatures, andthatasolidunderstandingofthesefeatures—in any language—willhelpthembe productiveinavarietyofprogramminglanguages,presentorfuture.
Theworldofprogramminglanguagesisvariedandcontinuestoevolveallthetime. Asadeveloper,youareexpectedtoadaptandtorepeatedlytransferyourprogramming skillsfromonelanguagetoanother.Learningnewprogramminglanguagesismadeeasier bymasteringasetofcorefeaturesthattoday’slanguagesoftenshare,andthatmany oftomorrow’slanguagesarelikelytouseaswell.
Programminglanguagefeaturesareillustratedinthisbookwithnumerouscode examples,primarilyinScala(forreasonsthataredetailedlater).Theconcepts,however, arerelevant—withvariousdegrees—tootherpopularlanguageslikeJava,C++,Kotlin, Python,C#,Swift,Rust,Go,JavaScript,andwhateverlanguagesmightpopupinthe futuretosupportstrongtypingaswellasfunctionaland/orconcurrentprogramming.
Asanillustrationofthedistinctionbetweenlanguagesandfeatures,considerthe followingprogrammingtask:
Shifteverynumberfromagivenlistbyarandomamountbetween -10 and 10.Returnalistofshiftednumbers,omittingallvaluesthatarenot positive.
AJavaprogrammermightimplementthedesiredfunctionasfollows:
List<Integer>randShift(List<Integer>nums,Randomrand){ var shiftedNums= new java.util.ArrayList<Integer>(nums.size()); for (int num:nums){ int shifted=num+rand.nextInt(-10,11); if (shifted>0)shiftedNums.add(shifted); } return shiftedNums; }
Java
APythonprogrammermightwritethisinstead:
def rand_shift(nums,rand): shifted_nums=[] for num in nums: shifted=num+rand.randrange(-10,11) if shifted>0: shifted_nums.append(shifted) return shifted_nums
Althoughtheyarewrittenintwodifferentlanguages,bothfunctionsfollowasimilar strategy:Createanewemptylisttoholdtheshiftednumbers,shifteachoriginalnumber byarandomamount,andaddthenewvaluestotheresultlistonlywhentheyare positive.Forallintentsandpurposes,thetwoprogramsarethesame.
Otherprogrammersmightchoosetoapproachtheproblemdifferently.Hereisone possibleJavavariant:
List<Integer>randShift(List<Integer>nums,Randomrand){ return nums.stream() .map(num->num+rand.nextInt(-10,11)) .filter(shifted->shifted>0) .toList();
The detailsofthisimplementationarenotimportantfornow—itreliesonfunctional programmingconceptsthatwillbediscussedinPartI.Whatmattersisthatthecode isnoticeablydifferentfromthepreviousJavaimplementation.
YoucanwriteasimilarfunctionalvariantinPython:
def rand_shift(nums,rand): return list(filter(lambda shifted:shifted>0, map(lambda num:num+rand.randrange(-10,11),nums)))
ThisimplementationisarguablyclosertothesecondJavavariantthanitistothefirst Pythonprogram.
Thesefourprogramsdemonstratetwodifferentwaystosolvetheoriginalproblem. Theycontrastanimperativeimplementation—inJavaorinPython—withafunctional implementation—again,inJavaorinPython.Whatfundamentallydistinguishesthe
Python
Java
Python
programsisnotthelanguages—JavaversusPython—butthefeaturesbeingused— imperativeversusfunctional.Theprogramminglanguagefeaturesusedintheimperativevariant(assignmentstatements,loops)andinthefunctionalvariant(higher-order functions,lambdaexpressions)existindependentlyfromJavaandPython;indeed,they areavailableinmanyprogramminglanguages.
Iamnotsayingthatprogramminglanguagesdon’tmatter.Weallknowthat,for agiventask,somelanguagesareabetterfitthanothers.ButIwanttoemphasize corefeaturesandconceptsthatextendacrosslanguages,evenwhentheyappearunder adifferentsyntax.Forinstance,anexperiencedPythonprogrammerismorelikelyto writetheexamplefunctionalprograminthisway:
def rand_shift(nums,rand):
return [shifted for shifted in (num+rand.randrange(-10,11) for num in nums) if shifted>0]
This codelooksdifferentfromtheearlierPythoncode—andthedetailsareagainunimportant.Noticethatfunctions map and filter arenowheretobeseen.Conceptually, though,thisisthesameprogrambutwrittenusingaspecificPythonsyntaxknownas listcomprehension,insteadof map and filter.
Theimportantconcepttounderstandhereistheuseof map and filter (andmore generallyhigher-orderfunctions,ofwhichtheyareanexample),notlistcomprehension. Youbenefitfromthisunderstandingintwoways.First,morelanguagessupporthigherorderfunctionsthanhaveacomprehensionsyntax.IfyouareprogramminginJava,for instance,youwillhavetowrite map and filter explicitly(atleastfornow).Second, ifyoueverfacealanguagethatusesasomewhatunusualsyntax,asPythondoeswith listcomprehension,itwillbeeasiertorecognizewhatisgoingononceyourealizethat itisjustavariationofaconceptyoualreadyunderstand.
Theprecedingcodeexamplesillustrateacontrastbetweenaprogramwritteninplain imperativestyleandonethatleveragesthefunctionalprogrammingfeaturesavailable inmanylanguages.Icanmakeasimilarargumentwithconcurrentprogramming.Languages(andlibraries)haveevolved,andthereisnoreasontowritetoday’sconcurrent programsthewaywedid20yearsago.Asasomewhatextremeexample,travelback notquite20yearsto2004,thedaysofJava1.4,andconsiderthefollowingproblem: Giventwotasksthateachproduceastring,invokebothtasksinparalleland returnthefirststringthatisproduced.
Assumeatype StringComputation withastring-producingmethod compute.In Java1.4,theproblemcanbesolvedasfollows(donottrytounderstandthecode;itis ratherlong,andthedetailsareunimportant):
Python
String firstOf(final StringComputationcomp1, final StringComputationcomp2) throws InterruptedException{ class Result{
private String value= null;
publicsynchronizedvoid setValue(String str){ if (value== null){ value=str; notifyAll(); } }
publicsynchronized String getValue() throws InterruptedException{ while (value== null) wait(); return value; } }
final Resultresult= new Result();
Runnabletask1= new Runnable(){ publicvoid run(){ result.setValue(comp1.compute()); } };
Runnabletask2= new Runnable(){ publicvoid run(){ result.setValue(comp2.compute()); }
};
new Thread(task1).start(); new Thread(task2).start(); return result.getValue(); }
Thisimplementationusesfeatureswithwhichyoumaynotbefamiliar(butwhichare coveredinPartIIofthebook).1 Herearetheimportantpointstonotice:
• Thecodeisabout30lineslong.
• Itrelieson synchronized methods,aformoflockingavailableintheJavaVirtual Machine(JVM).
1 Onereasonsuchold-fashionedfeaturesarestillcoveredinthisbookisthatIbelievetheyhelpus understandthericherandfancierconstructsthatweshouldbeusinginpractice.Theotherreasonis thattheconcurrentprogramminglandscapeisstillevolvingandrecentdevelopments,suchasvirtual threadsintheJavaVirtualMachine,havethepotentialtomaketheseolderconceptsrelevantagain.
Another random document with no related content on Scribd:
Tuolla heijastuu jo aamuruskon Ruusunpuna yli vuorien."
Ovi aukeaa ja sulo nainen,
Nuori, kaino, puhtaan kyyhkyn lainen,
Rientää aamun helmaan sulhon luo.
Kas, kuin posket hienot purppuroivat, Tuuleen tummat kutrit hulmuoivat.
Kevään otsallaan ja sydämessään
Taivaan immyt armaallensa tuo.
Tää kun näki silmät armahansa, Kuuli kuiskeen hänen huuliltansa:
Aksel! — silmistänsä raukes maa.
Vastaan riensi hän ja rinnoillensa
Painoi armaansa ja ainoisensa; Ja nyt ensi huomensuudelmasta Aunen huulet hehkui purppuraa.
Silloin nousi vuorten takaa päivä, Taivaan autereinen kultahäivä
Kuulti välkkyvänä hymyillen.
Lehdot helkkyi lintuin laulelosta,
Tuuli heräs aamun suutelosta;
Luonto loisti morsiamen lailla, Ja sen rinta sykki riemuiten.
Meri.
"Souda, souda kohti rantaa
Lapsi kulta luokse mun!
Kaikki tahdon anteeks antaa,
Sylihini nostan sun.
Anna aallon venhos kantaa Kohti rantaa."
Aallot syvät, aavat, summat
Mua yössä tuudittaa;
Kaukomaille vedet tummat
Mua kauas kantakaa!
Tuutikaa mua hiljaa tummat
Vedet summat.
"Kotilaaksossasi näätkö,
Monta tulta tuikkivi?
Karkeloista kauvas jäätkö?
Tullos sinne sinäki.
Anna aallon venhos kantaa Kohti rantaa."
Katso, kuinka tuolta loistaa
Kirkkaat tähdet tuhannet;
Taivaan valotarhan toistaa
Meren aallot riemuiset!
Mua yössä aallot hyvät
Tuutii syvät.
"Mustuu, mustuu, kauheasti
Peikot yössä uhkaavat,
Mutta kehtoon rauhaisasti
Lapsi kulta uinahdat.
Anna aallon venhos kantaa
Kohti rantaa."
Äiti, ei nuo vaahtohapset
Peikkoja lie laisinkaan, Luulen, että samat lapset
Tuttuja on vanhastaan.
Mua yössä aallot hyvät
Tuutii syvät.
"Varo armas, hukut varmaan
Aallon mustaan syvyyteen, Kuolo saapuu, haudan harmaan
Tuoni kaivaa uhrilleen.
Anna aallon venhos kantaa
Kohti rantaa."
Äiti, joskin hukun, varmaan
Pääsen siellä! taivohon,
Oi, se avaa helman armaan,
Oi, se taivas lähell' on.
Enkelit mua viittaa valoon
Tähtitaloon.
"Oi, mit' teet sä? aalto vento, Ällös ryöstä ainuttain!
Vielä vilkkuu käsi hento — Vilkkuu hetken, hetken vain.
Kutsuuko hän kädellänsä
Äitiänsä?"
Tuuli huokaa tuskiansa,
Aalto itkee rauhaton;
Vaan he helmihaudassansa
Uinuu luona Vellamon.
Runebergille.
Kun ilman raikkaat laulajat
Taas meille keväällä
Kanss' suvituulten saapuvat,
Pois lähdet täältä sä.
Kun luonto ihmissydämiin
Luo uutta kevättä
Ja valaa rauhaa niihin, niin
Pois täältä lähdet sä.
Sä lähdet aikaan keväimen
Ja haihdut kirkkaana
Kuin aamupilvi kultainen,
Mi liitää taivaalla.
Ja sydän sitä katseissa
Se toivoo, kaihoaa; —
Mut katso, nyt sen sijalla
Jo päivä heloittaa.
Jos minne saavut, kanneltas
Sä riemuin soittelet;
Ja runomaasta, kodistas, Sä ihmeet kertoilet.
Ja taivas seestyy, loistossaan
Maa on kuin morsio.
Ja yli vetten, yli maan
Soi kirkas kantelo.
Matkamuistelmia.
1. Hyvästi.
Kuin lempeinä loistatte, kotini kunnaat, Viitaten vaiti, vakavin katsein,
Ilta kun kultia luo!
Kuin ystävä kutsuvi rantani tuttu
Taas mua kodin metsien rauhaan; Siintävä tie, mua vie!
Pois mua tuutien kantavat laineet
Kauvaksi maasta vilkuttavasta, Lapsuuden lahdesta pois.
Ma jättänyt näin olen taattoni talon; Harmaiden vuorten takana tuolla
Rauhassa uinuvi se.
Mit' etsit sä kaukaa, siivekäs sielu?
Tuollako siintää kaihosi saaret
Vai kotilahdessa lie?
Sä riennät — sä riennät nyt majasta isäs, Lapsuuden laakson rauhasta riennät; Missä sun valkamas on?
Oi itkevä aaltonen! Rauhaton sielu
Elossa, kuoloss' saako se rauhaan, Määrähän tyydyttävään?
Mut aurinko laski ja usvat ne nousee
Mustasta veestä kätkien multa
Kaikki jo vaippahan yön.
Vain yksi on selvä; läp' aaltojen pauhun, Aatosten usvan kaikuvi aina: "Hyvästi, hyvästi jää!"
2. Tukholma. Tääll’ asuu kuningas. Kuin korkeana
Hän kohoaapi joukoss' sankarien
Ja kultakruunu loistaa kirkkahana, Sen näin mä unelmissa lapsuuden.
Nyt olen kyllä nähnyt kuninkaan mä, Mut muiden laiseksi näin hänet vaan mä Ja kruunua mä nähnyt en.
Tääll' eli suuri Kustaa Vaasa kerran,
Hän miesnä kantoi Svean valtikkaa;
Hän, kansan isä, palvelija Herran, Maaraukalleen soi rauhaa, kunniaa.
Tääll' olen nähnyt Kustaan kuvan jalon —
Se seisoo eessä Ritariston talon — Vaan kunniaa mä nähnyt en.
Ja näillä mailla Kustaa Aadolf varttui,
Ritari uljain joukon urhoisan;
Hän sankar'miekkaan puhtain käsin tarttui
Ja soti, kuoli eestä Jumalan. —
Nyt heidän mainetöitään kiittää kansa
Ja koristelee heidän hautojansa, Vaan urhoja mä nähnyt en.
Ja tänne tulin, sen nyt nähdä sain mä,
Mit' ennen lemmin synnynseudullan'.
Ja vuorikansan kunniata hain mä
Ja suuruutt' aatteitten ja toiminnan;
Mä suurten muistoin kotimaan näin siellä, Min kansa pientä puuhas pikkumiellä, Vaan muuta siellä nähnyt en.
3. Tervehdys Upsalalle.
Oi terve kuulu kaupunki,
sä sydän olet Sveanmaan, Sait rakkaan kodin rannoilta
mun tänne kauas kulkemaan!
Sua murhemielin tervehdin, sua vakavana tervehdin, On murhe minut vallannut ja valtaa vielä tänäänkin.
Kas tuolla puolen meren sen, mi huuhtoo rantaa Ruotsinmaan, On siellä laakso rauhaisa ja vuoret harmaat suojanaan, Siell' onpi maja äitini ja leikkikenttä lapsuuden,
Siell' asuu armaat olennot, mä sinne kaihoon jällehen.
Ne kaikki tunsi hyvin mun ja helli sylin avoimin,
Siell' oli riemu riemukkain ja rakkaus oi' rakkahin.
Kuin aamu raitis valoisa
siell' oli päivä jokainen, Ja tervein innoin sydän löi ja silmät säihkyi riemuiten.
Mut oi! Oi miksi tänne mun sä tenho-äänin viekoitit, Ja vapauttas, lauluas ja miehuuttas niin kiittelit?
Ett' toiveet rahkeet rinnastain kuin päivän säteet murtaui,
Ett' ilot kevään kalpeni ja sielu kasvoi, vakaantui.
On rakas äidin suudelma, on lämmin käsi toverin!
Mut ikikaiho polttavi ain' hurjaa rintaa kuitenkin.
Nuor' henki vihdoin heräjää Lumosta aamu-unelmain,
Ja sinä, kaunis maailma, Sen vedät pyörteihisi vain.
Niin heitin lapsuuskotini ja ystäväni lempivät, Ja kotikuusten huminan ja nurmen kukat viehkeät.
Mit' annettavaa sull' on nyt ilosta, jonka menetin?
Tää onko koti laulujen? Ja valon? Elon raittihin?
Oi hiljaa! Pelko, vavistus mun valtaa syvä kokonaan;
Tääll' uinuu suuret sankarit, mä seison heidän haudallaan.
Oi terve! Väkivarjoja näin kyllä kotivuorillain.
Mut onko Ruotsin lapsilla viel' urhovoima vanhempain?
4. Skon luostari.
Linna korkea, linna korkea, Haamu oot sinä päällä maan, Murhe haikea, murhe haikea Huokaa kauttasi kaihojaan.
Päivän kauttaaltaan, päivän kauttaaltaan Kuljin huoneesta huoneesen; Minne tulinkaan, minne tulinkaan, Seisoin vaiti ja vavisten.
Joka loukosta, joka loukosta, Katsoi aika, mi mennyt pois; Ja sen peittona, ja sen peittona On kuin miekka ja harso ois.
Katsellessani, katsellessani
Harso haljeten jakaantui, Silloin puoliksi, silloin puoliksi
Miekka välkkyvä paljastui.
Mitä silloin näin, mitä silloin näin, Sit' en kertoa konsaan voi; Mutta mielessäin, mutta mielessäin Monet aattehet kummat soi.
Murheest' itkin ma, murheest' itkin ma, Tuska ahdisti rintaa mun, Linna korkea, linna korkea, Haudan-synkässä saliss' sun!
Pois kun kiiruhdin, pois kun kiiruhdin,
Heitti laskeva aurinko
Mulle hyvästin, mulle hyvästin;
Ilta tummeni mailla jo.
Katkelmia.
Charlottelle.
Kuin yölehdokkikin, joka verhoon tuoksunsa peittää, Lempensä nainen myös rintahan kätkevi niin;
Lempeä etsivi hän, yhä lempeä, lempeä yksin, Tahtoen helmahan sen vaipuen riutua pois.
Armas, lempeä aina sa löytäös runsahin määrin; Mut vihan hallava jää luotasi pois pysyköön!
Marialle.
Elomme kevät kestää hetken vaan, Sen aamuriemu haihtuu joutuisaan; Sen kaikki kukat kuihtuu ajan käyden.
Oi viivy, viivy, lapsuus-unelma, Suo meille niinkuin entisaikoina
Soit hurskaan rauhan sekä riemun täyden! —
Kun elo herättää ja päivät mustiks muuttuu, Maa viel' on iloinen, mut meiltä ilo puuttuu.
Lauralle.
Äl' lausu: naisen maailma on ahdas, Ja elämänsä tyhjää, köyhää, turhaa!
Häll' onhan rinnassansa maailma!
Ja eikö taivaan kirkas valtakunta
Myös ole hänen, jos hän tahtoo vaan?
Vastasyntyneelle.
Ole tervetullut sa eloon!
Älä itke sä syntymätäs.
Näet taivahan, taivahan iloon
Käy Kristuksess' elämäs.
Jos tänne et tullut sa ois,
Et sinne sä tulla vois.
Morsian.
Luot maahan katseesi iloitsevan
Ja riemusi kätket rintahas,
Ja lailla lapsen rukoilevan
Niin hymyilet sä onneas.
Oi, mitä pyytää voisit vielä?
Sait lempimäsi ystävän.
Hän luonas on ja riemumiellä
Sua omaksensa kutsuu hän.
Kuin suloisia lemmen päivät
On elon kevään lämpöisen!
Kuin väistyy kaikki huolten häivät, Kun sydän sykkii lempien!
Oi terve! sinun nuoruutesi
Nyt lempi täyttää tenhollaan.
Oi kestäköhön toivoinesi
Hääaikas armas ainiaan!
Eräs yö.
Pois lähti saattojoukko hiljainen,
Ja vaiennut on soitto kellojen;
He haudan kylmään multaan kätki kuolleen.
Ja kun he haudan multaan kätki kuolleen,
Sai tyyni yö, ja varjovaipallaaan
Se peitti kaiken maan.
Mut yksin luokse kuolleen ystävän
Pois ihmishälinästä kääntyi hän
Ja seisattui, miss' ystävänsä uinui.
Hän seisattui, miss' ystävänsä uinui,
Ja murtuneena, vaiti, kolkkona, Hän seisoi haudalla.
Ja murtuneena hautaa katsoi hän;
Yö mustui, mustui yhä enemmän,
Ja peittyi kuu, ja kaikki tähdet sammui.
Kun peittyi kuu, ja kaikki tähdet sammui,
Niin murtui rintansa, ja tuliset
Vuos' maahan kyynelet
Ja kaikki myrskyt rinnan raadellun,
Ja vaikerrukset mielen murretun
Ne Jumala ja yö vain yksin kuuli.
Ja Jumala ja yö vain yksin kuuli,
Kuin hälle kallis se, min hauta vei,
Eik' enää anna, ei.
Ja kun yön pitkän pilvet poissa on,
Niin ensisäteiss' aamuauringon
Viel' itki haudalla hän ristin alla,
Kun itki haudalla hän ristin alla,
Niin aamutuuli posken kalvenneen
Pois pyyhki kyyneleen.
Mut ilmat lintuin lauleloita soi,
Se rauhaa jälleen hälle rintaan toi; —
Kanss' aamunkoiton lohtuaan toi Luoja.
Kanss' aamunkoiton lohtuaan toi Luoja,
Hän riemun, sovinnon sai jällehen
Ja nousi rukoillen:
"Oi sä, mi kautta kuolon laaksojen
Viet matkamiehen kirkkautehen,
Oi kiitos! — haudass' synkäss' ei hän uinu;
Ei haudassa hän synkässä nyt uinu,
Oi ei! hän helläss' istuu helmassas, Ja kuulee lohtuas."
Hän läksi, eli niinkuin ennenkin
Ja kantoi taakkaa mielin kärsivin,
Ei kenkään hänen valitustaan kuullut.
Ei kenkään hänen valitustaan kuullut,
Mut sydämessään kirkas, tahraton
Tuo kuva kallis on.
Tyttö.
Yö mustan vaippansa maille heitti,
Ja taivaan tähtiä pilvet peitti,
Vain öinen myrsky se raivoissaan
Viel’ ulvoi ulkona kautta maan.
Hän yksin istui, ei nähnyt yötä,
Ei mustaa maitten ja vetten vyötä;
Pää kättä vastaan hän huokaa niin
Ja puhkee kuumihin kyyneliin.
On synkkä, rauhaton hällä rinta, Hän tuskaa miettivi katkerinta:
"Mä yksin oon, mua päällä maan
Ei muista ystävä ainutkaan.
Mä kelle tuskani itkenenkään,
Ei valitustani kuule kenkään,
Ei ketään, ken mua lohduttais, Ken kyynelvirtani kuivajais.
Ei mulle riemua mailmass' suotu,
En kellekään ole riemuks luotu, Mut elää, kärsiä yksin vain, Se on, oi, synkkänä osanain."
Oi raukka, tuskas ma tunnen syvät; —
Mut Herran enkelit kirkkaat, hyvät,
Jos luonas lohtuna näkisit, Niin itkus' iloksi tekisit.
Ne tahtois sieluas lohdutella
Ja ikuisuudesta kertoella;
Ne nostais silmäsi taivoon päin
Sun elon toivohon ylentäin.
Jos heitä kuulisit, elos saisit
Ja rauhan rintahas rakentaisit;
Jos sull' ois usko, niin sua jo
Nyt armon valaisis aurinko.
Kun heidät sydämes ulos sulkee, Niin luotas tuskalla pois he kulkee, Eik' koskaan rintasi rauhaa saa, Läp' elos täytyy sun valittaa.
Sanat Maisterinvihkiäisissä 1836.
Koraali.
Kun synkkä viipyy murheen yö,
Kun riemujuhlin rinnat lyö,
Niin katse Herraan kääntyy yhä.
On lokaa loistot maalliset,
On turhaa laaker'seppelet,
Jos poiss' on, Herra, armos pyhä.
Jos Zebaoth oot läsnä, oi,
Ken vastustaa meit' enää voi?
Ain' ollos meidän suojana;
Oot armollinen, mahtava,
Ja täytät sanas, jotka annoit.
Oi ollos mestarimme sa,
Jok' astuit alas taivaasta
Ja kärsit, okakruunun kannoit!
Sun oomme me, sun ainian
Kautt' elämän ja kuoleman.
Kööri (Riemumaistereille). [Musiikki Spohr'in sävellyksestä "Die letzten Dinge"].
Terve Teille! ihana lasketaan laakeri teidän hopeaisille hiuksillenne, tuore kuin ennen muinoin. Terve Teille! Jumala on paremman seppeleen, pyhän, ikuisen, ehkä tämän jälkeen otsallenne laskeva!
Kööri (Maistereille).
Nosta ylös silmäsi, nuori valon vartio! Katso, Jumala on lähellä. Nosta ylös silmäsi, sillä Herra on sinua lähellä, kaikkivaltias, täynnä
armoa ja totuutta. Itse hän tahtoo vihkiä sinut omaksi ja totuuden palvelijaksi. Hän antaa sinulle seppeleesi; kaikki kunnia on Hänen.
Soolo.
Älä pelkää! sillä Jumalasi tahto on antaa sinulle valtakunta. Oikealla kädellään on Hän sinulle paikan määrännyt korkeudessa.
Kööri.
Siis lähteös taisteluun, nuori joukko, valon taisteluun lyhyeksi aikaa! Mene ja taistele rohkeasti, niin kauvan kuin päivä on, kaiken sen puolesta, mikä totta ja oikeaa on päällä maan. Ole uskollinen kuolemaan saakka, niin on Hän sinulle elämän seppeleen antava.
Kööri (vihkimisen jälkeen).
Vihitty on joukko, luottain
Lähtee nyt se taistohon;
Vaaraa turvallisna vuottain, Sillä rohkea se on.
Hornan henki kätkenyt on Kaikkialle joukkojaan;
Miehet jalot kaikki nyt on Kutsuttuna sotimaan.
Herra tuntee sotilaansa, Kruunaa heidät hengellään, Kuuluttamaan kunniaansa, Aatteitansa täyttämään.
Laakerilla kuihtuvalla
Kruunaa hänet ihmiset;
Jos hän taistelee sen alla, "Amen" vastaa tuhannet.
Finale.
Sun kätes ojenna
Ja suojaa Suomea;
Oi Luojamme.
Ja siunaa Keisari,
Tee hänet vahvaksi;
Viel' olkoon kauvanki
Hän suojamme!
Sun kätes ojenna
Ja kylvä viisautta;
Oot valomme.
Ja rauhan totuuden
Luo valta Suomehen;
Ja uskoss' isien
Sä pidä se!
Ylioppilaslaulu.
Niin kauvan kuin syömemme sykkivi vaan,
Veri kiehuu ja poskemme palaa,
Niin kauvan kuin nuoruus kukkuranaan
Yhä voimaa ja riemua valaa;
On totuus loistava retkemme pää,
Ei kenkään viivy, ei kenkään jää, Nyt velttona varjoon ja uneen.
Hupi inhoksi käy, tupa ahdas jo on,
Elo mahtava kutsuvi meitä;
Sitä tahdomme seurata kuolohon Ylös kunnian kirkkaita teitä.
Toden templihin sielumme kaihoelee; Liput liehuvi, kantelet kaikuelee, Kun joukkomme rientävi sinne.
Siis riemuiten yhtehen yhdymme nyt, Viel' liittomme vanha on pyhä.
Se henki, mi meitä on lämmittänyt, On vahva ja kestävi yhä;
Ain' uutehen hehkuun se rintamme saa, Ja kerran sä, kallehin syntymämaa, Ilon meist' olet runsahan saapa.
H. G. Porthanin muistojuhlassa, 9 p. marrask. 1839.
J. L. Runebergin malja.
Kun päivyt laskee meren sini-aaltoihin, Ja illan rusko nousevi ja levittäin
Luo kultapeitteensä sen vuoteen ylitse,
Mut itse kuitenkin on päivän heijastus, Mi lupaa loistavana kaunist' aamua;
Niin, veljet, vaipui myös se jalo mies,