Escolar Documentos
Profissional Documentos
Cultura Documentos
Tutorials
Javaconcurrency(multithreading)Tutorial
Services
Products
Books
Blog
Donate
Search
Contact us
Javaconcurrency(multithreading)Tutorial
AdOptions
AdsbyInfo
LarsVogel
Version2.3
Copyright2008,2009,2010,2011,2012,2013vogellaGmbH
02.08.2013
Javaconcurrency(multithreading)
ThisarticledescribeshowtodoconcurrentprogrammingwithJava.Itcoverstheconceptsof
parallelprogramming,immutability,threads,theexecutorframework(threadpools),futures,
callablesandtheforkjoinframework.
TableofContents
1.Concurrency
1.1.Whatisconcurrency?
1.2.Processvs.threads
2.Improvementsandissueswithconcurrency
2.1.Limitsofconcurrencygains
2.2.Concurrencyissues
3.ConcurrencyinJava
3.1.ProcessesandThreads
3.2.Locksandthreadsynchronization
3.3.Volatile
4.TheJavamemorymodel
4.1.Overview
4.2.Atomicoperation
4.3.Memoryupdatesinsynchronizedcode
5.ImmutabilityandDefensiveCopies
5.1.Immutability
5.2.DefensiveCopies
6.ThreadsinJava
7.ThreadspoolswiththeExecutorFramework
8.FuturesandCallables
9.Nonblockingalgorithms
10.ForkJoininJava7
11.Deadlock
12.Aboutthiswebsite
12.1.Donatetosupportfreetutorials
12.2.Questionsanddiscussion
12.3.Licenseforthistutorialanditscode
13.LinksandLiterature
13.1.SourceCode
13.2.ConcurrencyResources
13.3.vogellaResources
AdsbyInfo
http://www.vogella.com/tutorials/JavaConcurrency/article.html
AdOptions
1/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
1.Concurrency
1.1.Whatisconcurrency?
Concurrencyistheabilitytorunseveralprogramsorseveralpartsofaprograminparallel.Ifa
timeconsumingtaskcanbeperformedasynchronouslyorinparallel,thisimprovethethroughput
andtheinteractivityoftheprogram.
AmoderncomputerhasseveralCPU'sorseveralcoreswithinoneCPU.Theabilitytoleverage
thesemulticorescanbethekeyforasuccessfulhighvolumeapplication.
1.2.Processvs.threads
Aprocessrunsindependentlyandisolatedofotherprocesses.Itcannotdirectlyaccessshared
datainotherprocesses.Theresourcesoftheprocess,e.g.memoryandCPUtime,areallocated
toitviatheoperatingsystem.
Athreadisasocalledlightweightprocess.Ithasitsowncallstack,butcanaccessshareddataof
otherthreadsinthesameprocess.Everythreadhasitsownmemorycache.Ifathreadreads
shareddataitstoresthisdatainitsownmemorycache.Athreadcanrereadtheshareddata.
AJavaapplicationrunsbydefaultinoneprocess.WithinaJavaapplicationyouworkwithseveral
threadstoachieveparallelprocessingorasynchronousbehavior.
2.Improvementsandissueswithconcurrency
WithinaJavaapplicationyouworkwithseveralthreadstoachieveparallelprocessingor
asynchronousbehavior.
2.1.Limitsofconcurrencygains
Concurrencypromisestoperformcertaintaskfasterasthesetaskscanbedividedintosubtasks
andthesesubtaskscanbeexecutedinparallel.Ofcoursetheruntimeislimitedbypartsofthe
taskwhichcanbeperformedinparallel.
Thetheoreticalpossibleperformancegaincanbecalculatedbythefollowingrulewhichisreferred
toasAmdahl'sLaw.
IfFisthepercentageoftheprogramwhichcannotruninparallelandNisthenumberof
processes,thenthemaximumperformancegainis1/(F+((1F)/n)).
2.2.Concurrencyissues
Threadshavetheirowncallstack,butcanalsoaccessshareddata.Thereforeyouhavetwobasic
problems,visibilityandaccessproblems.
AvisibilityproblemoccursifthreadAreadsshareddatawhichislaterchangedbythreadBand
threadAisunawareofthischange.
Anaccessproblemcanoccurifseveralthreadaccessandchangethesameshareddataatthe
sametime.
Visibilityandaccessproblemcanleadto
Livenessfailure:Theprogramdoesnotreactanymoreduetoproblemsintheconcurrent
accessofdata,e.g.deadlocks.
Safetyfailure:Theprogramcreatesincorrectdata.
3.ConcurrencyinJava
3.1.ProcessesandThreads
AJavaprogramrunsinitsownprocessandbydefaultinonethread.Javasupportsthreadsas
partoftheJavalanguageviathe Thread code.TheJavaapplicationcancreatenewthreadsvia
thisclass.
Java1.5alsoprovidesimprovedsupportforconcurrencywiththeinthe java.util.concurrent
package.
3.2.Locksandthreadsynchronization
Javaprovideslockstoprotectcertainpartsofthecodetobeexecutedbyseveralthreadsatthe
sametime.ThesimplestwayoflockingacertainmethodorJavaclassistodefinethemethodor
classwiththe synchronized keyword.
ThesynchronizedkeywordinJavaensures:
thatonlyasinglethreadcanexecuteablockofcodeatthesametime
thateachthreadenteringasynchronizedblockofcodeseestheeffectsofallprevious
http://www.vogella.com/tutorials/JavaConcurrency/article.html
2/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
modificationsthatwereguardedbythesamelock
Synchronizationisnecessaryformutuallyexclusiveaccesstoblocksofandforreliable
communicationbetweenthreads.
Youcanusethesynchronizedkeywordforthedefinitionofamethod.Thiswouldensurethatonly
onethreadcanenterthismethodatthesametime.Anotherthreadswhichiscallingthismethod
wouldwaituntilthefirstthreadsleavesthismethod.
publicsynchronizedvoidcritial(){
//somethreadcriticalstuff
//here
}
/**
*Getnextsitetocrawl.Canreturnnull(ifnothingtocrawl)
*/
publicStringnext(){
if(linkedSites.size()==0){
returnnull;
}
synchronized(this){
//Needtocheckagainifsizehaschanged
if(linkedSites.size()>0){
Strings=linkedSites.get(0);
linkedSites.remove(0);
crawledSites.add(s);
returns;
}
returnnull;
}
}
}
3.3.Volatile
Ifavariableisdeclaredwiththevolatilekeywordthenitisguaranteedthatanythreadthatreads
thefieldwillseethemostrecentlywrittenvalue.Thevolatilekeywordwillnotperformanymutual
exclusivelockonthevariable.
AsofJava5writeaccesstoavolatilevariablewillalsoupdatenonvolatilevariableswhichwere
modifiedbythesamethread.Thiscanalsobeusedtoupdatevalueswithinareferencevariable,
e.g.foravolatilevariableperson.Inthiscaseyoumustuseatemporaryvariablepersonanduse
thesettertoinitializethevariableandthenassignthetemporaryvariabletothefinalvariable.This
willthenmaketheaddresschangesofthisvariableandthevaluesvisibletootherthreads.
http://www.vogella.com/tutorials/JavaConcurrency/article.html
3/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
AdOptions
AdsbyInfo
4.TheJavamemorymodel
4.1.Overview
TheJavamemorymodeldescribesthecommunicationbetweenthememoryofthethreadsand
themainmemoryoftheapplication.
Itdefinestheruleshowchangesinthememorydonebythreadsarepropagatedtootherthreads.
TheJavamemorymodelalsodefinesthesituationsinwhichathreadrefreshitsownmemory
fromthemainmemory.
Italsodescribeswhichoperationsareatomicandtheorderingoftheoperations.
4.2.Atomicoperation
Anatomicoperationisanoperationwhichisperformedasasingleunitofworkwithoutthe
possibilityofinterferencefromotheroperations.
TheJavalanguagespecificationguaranteesthatreadingorwritingavariableisanatomic
operation(unlessthevariableisoftype long or double ).Operationsvariablesoftype long or
double areonlyatomiciftheydeclaredwiththe volatile keyword..
Assume i isdefinedas int .The i++ (increment)operationitnotanatomicoperationinJava.
Thisalsoappliesfortheothernumerictypes,e.g.long.etc).
The i++ operationfirstreadsthevaluewhichiscurrentlystoredini(atomicoperations)andthen
itaddsonetoit(atomicoperation).Butbetweenthereadandthewritethevalueofimighthave
changed.
SinceJava1.5thejavalanguageprovidesatomicvariables,e.g.AtomicIntegerorAtomicLong
whichprovidemethodslike getAndDecrement() , getAndIncrement() and getAndSet() which
areatomic.
4.3.Memoryupdatesinsynchronizedcode
TheJavamemorymodelguaranteesthateachthreadenteringasynchronizedblockofcodesees
theeffectsofallpreviousmodificationsthatwereguardedbythesamelock.
5.ImmutabilityandDefensiveCopies
5.1.Immutability
Thesimplestwaytoavoidproblemswithconcurrencyistoshareonlyimmutabledatabetween
threads.Immutabledataisdatawhichcannotchanged.
Tomakeaclassimmutablemake
allitsfieldsfinal
theclassdeclaredasfinal
thethisreferenceisnotallowedtoescapeduringconstruction
Anyfieldswhichrefertomutabledataobjectsare
private
havenosettermethod
http://www.vogella.com/tutorials/JavaConcurrency/article.html
4/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
theyareneverdirectlyreturnedofotherwiseexposedtoacaller
iftheyarechangedinternallyintheclassthischangeisnotvisibleandhasnoeffect
outsideoftheclass
Animmutableclassmayhavesomemutabledatawhichisusestomanagesitsstatebutfromthe
outsidethisclassnoranyattributeofthisclasscangetchanged.
Forallmutablefields,e.g.Arrays,thatarepassedfromtheoutsidetotheclassduringthe
constructionphase,theclassneedstomakeadefensivecopyoftheelementstomakesurethat
nootherobjectfromtheoutsidestillcanchangethedata
5.2.DefensiveCopies
Youmustprotectyourclassesfromcallingcode.Assumethatcallingcodewilldoitsbestto
changeyourdatainawayyoudidn'texpectit.Whilethisisespeciallytrueincaseofimmutable
dataitisalsotruefornonimmutabledatawhichyoustillnotexpectthatthisdataischanged
outsideyourclass.
Toprotectyourclassagainstthatyoushouldcopydatayoureceiveandonlyreturncopiesofdata
tocallingcode.
Thefollowingexamplecreatesacopyofalist(ArrayList)andreturnsonlythecopyofthelist.This
waytheclientofthisclasscannotremoveelementsfromthelist.
packagede.vogella.performance.defensivecopy;
importjava.util.ArrayList;
importjava.util.Collections;
importjava.util.List;
publicclassMyDataStructure{
List<String>list=newArrayList<String>();
publicvoidadd(Strings){
list.add(s);
}
/**
*MakesadefensivecopyoftheListandreturnit
*Thiswaycannotmodifythelistitself
*
*@returnList<String>
*/
publicList<String>getList(){
returnCollections.unmodifiableList(list);
}
}
6.ThreadsinJava
Thebasemeansforconcurrencyareisthe java.lang.Threads class.A Thread executesan
objectoftype java.lang.Runnable .
Runnable isaninterfacewithdefinesthe run() method.Thismethodiscalledbythe Thread
objectandcontainstheworkwhichshouldbedone.Thereforethe"Runnable"isthetaskto
perform.TheThreadistheworkerwhoisdoingthistask.
Thefollowingdemonstratesatask(Runnable)whichcountsthesumofagivenrangeofnumbers.
CreateanewJavaprojectcalled de.vogella.concurrency.threads fortheexamplecodeofthis
section.
packagede.vogella.concurrency.threads;
/**
*MyRunnablewillcountthesumofthenumberfrom1totheparameter
*countUntilandthenwritetheresulttotheconsole.
*<p>
*MyRunnableisthetaskwhichwillbeperformed
*
*@authorLarsVogel
*
*/
publicclassMyRunnableimplementsRunnable{
privatefinallongcountUntil;
MyRunnable(longcountUntil){
http://www.vogella.com/tutorials/JavaConcurrency/article.html
5/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
this.countUntil=countUntil;
}
@Override
publicvoidrun(){
longsum=0;
for(longi=1;i<countUntil;i++){
sum+=i;
}
System.out.println(sum);
}
}
AdsbyInfo
http://www.vogella.com/tutorials/JavaConcurrency/article.html
AdOptions
6/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
7.ThreadspoolswiththeExecutorFramework
Tip: You find this examples in the source section in Java project called
de.vogella.concurrency.threadpools.
Threadpoolsmanageapoolofworkerthreads.Thethreadpoolscontainsaworkqueuewhich
holdstaskswaitingtogetexecuted.
Athreadpoolcanbedescribedasacollectionof Runnable objects(workqueue)anda
connectionsofrunningthreads.Thesethreadsareconstantlyrunningandarecheckingthework
queryfornewwork.IfthereisnewworktobedonetheyexecutethisRunnable.TheThreadclass
itselfprovidesamethod,e.g.execute(Runnabler)toaddanew Runnable objecttothework
queue.
TheExecutorframeworkprovidesexampleimplementationofthejava.util.concurrent.Executor
interface,e.g.Executors.newFixedThreadPool(intn)whichwillcreatenworkerthreads.The
ExecutorServiceaddslifecyclemethodstotheExecutor,whichallowstoshutdowntheExecutor
andtowaitfortermination.
Tip: If you want to use one thread pool with one thread which executes
several runnables you can use the
Executors.newSingleThreadExecutor()
method.
CreateagaintheRunnable.
packagede.vogella.concurrency.threadpools;
/**
*MyRunnablewillcountthesumofthenumberfrom1totheparameter
*countUntilandthenwritetheresulttotheconsole.
*<p>
*MyRunnableisthetaskwhichwillbeperformed
*
*@authorLarsVogel
*
*/
publicclassMyRunnableimplementsRunnable{
privatefinallongcountUntil;
MyRunnable(longcountUntil){
this.countUntil=countUntil;
}
@Override
publicvoidrun(){
longsum=0;
for(longi=1;i<countUntil;i++){
sum+=i;
}
System.out.println(sum);
}
}
Nowyourunyourrunnableswiththeexecutorframework.
packagede.vogella.concurrency.threadpools;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
publicclassMain{
privatestaticfinalintNTHREDS=10;
publicstaticvoidmain(String[]args){
ExecutorServiceexecutor=Executors.newFixedThreadPool(NTHREDS);
for(inti=0;i<500;i++){
Runnableworker=newMyRunnable(10000000L+i);
executor.execute(worker);
}
//Thiswillmaketheexecutoracceptnonewthreads
//andfinishallexistingthreadsinthequeue
executor.shutdown();
//Waituntilallthreadsarefinish
executor.awaitTermination();
System.out.println("Finishedallthreads");
}
http://www.vogella.com/tutorials/JavaConcurrency/article.html
7/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
}
Incasethethreadsshouldreturnsomevalue(resultbearingthreads)thenyoucanusethe
java.util.concurrent.Callable class.
8.FuturesandCallables
ThecodeexamplesforthissectionarecreatedinaJavaprojectcalled
de.vogella.concurrency.callables.
Theexecutorframeworkpresentedinthelastchapterworkswith Runnables .Runnabledonot
returnresult.
Incaseyouexpectyourthreadstoreturnacomputedresultyoucanuse
java.util.concurrent.Callable .The Callable objectallowstoreturnvaluesaftercompletion.
The Callable objectusesgenericstodefinethetypeofobjectwhichisreturned.
Ifyousubmita Callable objecttoan Executor theframeworkreturnsanobjectoftype
java.util.concurrent.Future .This Future objectcanbeusedtocheckthestatusofa
Callable andtoretrievetheresultfromthe Callable .
packagede.vogella.concurrency.callables;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.concurrent.Callable;
importjava.util.concurrent.ExecutionException;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.Future;
publicclassCallableFutures{
privatestaticfinalintNTHREDS=10;
publicstaticvoidmain(String[]args){
ExecutorServiceexecutor=Executors.newFixedThreadPool(NTHREDS);
List<Future<Long>>list=newArrayList<Future<Long>>();
for(inti=0;i<20000;i++){
Callable<Long>worker=newMyCallable();
Future<Long>submit=executor.submit(worker);
list.add(submit);
}
longsum=0;
System.out.println(list.size());
//nowretrievetheresult
for(Future<Long>future:list){
try{
sum+=future.get();
}catch(InterruptedExceptione){
e.printStackTrace();
}catch(ExecutionExceptione){
e.printStackTrace();
}
}
System.out.println(sum);
executor.shutdown();
}
}
http://www.vogella.com/tutorials/JavaConcurrency/article.html
8/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
9.Nonblockingalgorithms
Java5.0providessupportsforadditionalatomicoperations.Thisallowstodevelopalgorithmwhich
arenonblockingalgorithm,e.g.whichdonotrequiresynchronization,butarebasedonlowlevel
atomichardwareprimitivessuchascompareandswap(CAS).Acompareandswapoperation
checkifthevariablehasacertainvalueandifithasthisvalueitwillperformthisoperation.
Nonblockingalgorithmareusuallymuchfasterthenblockingalgorithmsasthesynchronizationof
threadsappearsonamuchfinerlevel(hardware).
Forexamplethiscreatedanonblockingcounterwhichalwaysincreases.Thisexampleis
containedintheprojectcalledde.vogella.concurrency.nonblocking.counter.
packagede.vogella.concurrency.nonblocking.counter;
importjava.util.concurrent.atomic.AtomicInteger;
publicclassCounter{
privateAtomicIntegervalue=newAtomicInteger();
publicintgetValue(){
returnvalue.get();
}
publicintincrement(){
returnvalue.incrementAndGet();
}
//Alternativeimplementationasincrementbutjustmakethe
//implementationexplicit
publicintincrementLongVersion(){
intoldValue=value.get();
while(!value.compareAndSet(oldValue,oldValue+1)){
oldValue=value.get();
}
returnoldValue+1;
}
Andatest.
packagede.vogella.concurrency.nonblocking.counter;
importjava.util.ArrayList;
importjava.util.HashSet;
importjava.util.List;
importjava.util.Set;
importjava.util.concurrent.Callable;
importjava.util.concurrent.ExecutionException;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.Future;
publicclassTest{
privatestaticfinalintNTHREDS=10;
publicstaticvoidmain(String[]args){
finalCountercounter=newCounter();
List<Future<Integer>>list=newArrayList<Future<Integer>>();
ExecutorServiceexecutor=Executors.newFixedThreadPool(NTHREDS);
for(inti=0;i<500;i++){
Callable<Integer>worker=newCallable<Integer>(){
@Override
publicIntegercall()throwsException{
intnumber=counter.increment();
System.out.println(number);
returnnumber;
}
};
Future<Integer>submit=executor.submit(worker);
list.add(submit);
}
//Thiswillmaketheexecutoracceptnonewthreads
//andfinishallexistingthreadsinthequeue
executor.shutdown();
//Waituntilallthreadsarefinish
while(!executor.isTerminated()){
http://www.vogella.com/tutorials/JavaConcurrency/article.html
9/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
}
Set<Integer>set=newHashSet<Integer>();
for(Future<Integer>future:list){
try{
set.add(future.get());
}catch(InterruptedExceptione){
e.printStackTrace();
}catch(ExecutionExceptione){
e.printStackTrace();
}
}
if(list.size()!=set.size()){
thrownewRuntimeException("Doubleentries!!!");
}
}
TheJDKitselfmakesmoreandmoreuseofnonblockingalgorithmstoincreaseperformancefor
everydeveloper.Developingcorrectnonblockingalgorithmisnotatrivialtask.
Formoreinformationonnonblockingalgorithm,e.g.examplesforanonblockingStackandnon
blockLinkedList,pleaseseehttp://www.ibm.com/developerworks/java/library/j
jtp04186/index.html
AdsbyInfo
AdOptions
10.ForkJoininJava7
Java7introduceanewparallelmechanismforcomputeintensivetasks,theforkjoinframework.
Theforkjoinframeworkallowsyoutodistributeacertaintaskonseveralworkersandthenwaitfor
theresult.
EForJava6.0youcandownloadthepackage(jsr166y)fromDownloadsite
FortestingcreatetheJavaproject"de.vogella.performance.forkjoin".IfyouarenotusingJava7
youalsoneedtojsr166y.jartotheclasspath.
Createfirsta algorithm packageandthenthefollowingclass.
packagealgorithm;
importjava.util.Random;
/**
*
*Thisclassdefinesalonglistofintegerswhichdefinestheproblemwewill
*latertrytosolve
*
*/
http://www.vogella.com/tutorials/JavaConcurrency/article.html
10/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
publicclassProblem{
privatefinalint[]list=newint[2000000];
publicProblem(){
Randomgenerator=newRandom(19580427);
for(inti=0;i<list.length;i++){
list[i]=generator.nextInt(500000);
}
}
publicint[]getList(){
returnlist;
}
}
Tip: The API defines other top classes, e.g. RecursiveAction, AsyncAction.
Check the Javadoc for details.
packagealgorithm;
importjava.util.Arrays;
importjsr166y.forkjoin.RecursiveAction;
publicclassSolverextendsRecursiveAction{
privateint[]list;
publiclongresult;
publicSolver(int[]array){
this.list=array;
}
@Override
protectedvoidcompute(){
if(list.length==1){
result=list[0];
}else{
intmidpoint=list.length/2;
int[]l1=Arrays.copyOfRange(list,0,midpoint);
int[]l2=Arrays.copyOfRange(list,midpoint,list.length);
Solvers1=newSolver(l1);
Solvers2=newSolver(l2);
forkJoin(s1,s2);
result=s1.result+s2.result;
}
}
}
Nowdefineasmalltestclassfortestingitefficiency.
packagetesting;
importjsr166y.forkjoin.ForkJoinExecutor;
importjsr166y.forkjoin.ForkJoinPool;
importalgorithm.Problem;
importalgorithm.Solver;
publicclassTest{
publicstaticvoidmain(String[]args){
Problemtest=newProblem();
//checkthenumberofavailableprocessors
intnThreads=Runtime.getRuntime().availableProcessors();
System.out.println(nThreads);
Solvermfj=newSolver(test.getList());
ForkJoinExecutorpool=newForkJoinPool(nThreads);
pool.invoke(mfj);
longresult=mfj.getResult();
System.out.println("Done.Result:"+result);
longsum=0;
//checkiftheresultwasok
for(inti=0;i<test.getList().length;i++){
sum+=test.getList()[i];
}
System.out.println("Done.Result:"+sum);
}
http://www.vogella.com/tutorials/JavaConcurrency/article.html
11/13
2/11/2015
Javaconcurrency(multithreading)Tutorial
}
11.Deadlock
Aconcurrentapplicationhastheriskofadeadlock.Asetofprocessesaredeadlockedifall
processesarewaitingforaneventwhichanotherprocessinthesamesethastocause.
ForexampleifthreadAwaitsforalockonobjectZwhichthreadBholdsandthreadBwaitfora
lookonobjectYwhichisholdbeprocessAthenthesetwoprocessesarelookedandcannot
continueintheirprocessing.
12.Aboutthiswebsite
12.1.Donatetosupportfreetutorials
Pleaseconsideracontribution
andourOpenSourceactivities.
ifthisarticlehelpedyou.Itwillhelptomaintainourcontent
12.2.Questionsanddiscussion
Writingandupdatingthesetutorialsisalotofwork.Ifthisfreecommunityservicewashelpful,you
cansupportthecausebygivingatipaswellasreportingtyposandfactualerrors.
Ifyoufinderrorsinthistutorial,pleasenotifyme(seethetopofthepage).Pleasenotethatdue
tothehighvolumeoffeedbackIreceive,Icannotanswerquestionstoyourimplementation.
EnsureyouhavereadthevogellaFAQasIdon'trespondtoquestionsalreadyansweredthere.
12.3.Licenseforthistutorialanditscode
ThistutorialisOpenContentundertheCCBYNCSA3.0DElicense.Sourcecodeinthistutorial
isdistributedundertheEclipsePublicLicense.SeethevogellaLicensepagefordetailsonthe
termsofreuse.
AdsbyInfo
AdOptions
13.LinksandLiterature
13.1.SourceCode
SourceCodeofExamples
13.2.ConcurrencyResources
http://java.sun.com/docs/books/tutorial/essential/concurrency/index.htmlIntroductionto
Concurrency
http://www.briangoetz.com/pubs.htmlArticleseriesfromBrianGoetzincludinglotsabout
concurrency
http://www.ibm.com/developerworks/library/jjtp0730.htmlThreadpoolsandworkqueuesby
BrianGoetz
http://www.ibm.com/developerworks/java/library/jjtp04186/index.htmlIntroductionto
nonblockingalgorithmsbyBrianGoetz
http://www.ibm.com/developerworks/java/library/jjtp11137.htmlJavatheoryandpractice:
Stickaforkinit,Part1byBrianGoetz
http://www.ibm.com/developerworks/java/library/jjtp03048.htmlJavatheoryandpractice:
http://www.vogella.com/tutorials/JavaConcurrency/article.html
12/13