




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
JAVA多線(xiàn)程實(shí)現(xiàn)方JAVAThreadRunnable接口、使用繼承ThreadRunnable接口的一個(gè)實(shí)例,它代表一個(gè)線(xiàn)程的實(shí)例,并且,啟動(dòng)線(xiàn)程的唯一方法就是通Thread類(lèi)的start()實(shí)例方法。start()native方法,它將啟動(dòng)一個(gè)新線(xiàn)run()extendThread,并復(fù)寫(xiě)run()方法,就可以啟動(dòng)新線(xiàn)程并執(zhí)行自己定義的run()方法。例如:publicclassMyThreadextendsThread{publicvoidrun(){}}MyThreadmyThread1=newMyThread();MyThreadmyThread2=newMyThread();實(shí)現(xiàn)Runnable接口方式實(shí)現(xiàn)多extendsextendsThread,此時(shí),必須實(shí)現(xiàn)一Runnable接口,如下:publicclassMyThreadextendsOtherClassimplementsRunnable{publicvoidrun(){}}為了啟動(dòng)MyThread,需要首先實(shí)例化一個(gè)Thread,并傳入自己的MyThread實(shí)例MyThreadmyThread=newMyThread();Threadthread=newThread(myThread);事實(shí)上,當(dāng)傳入一個(gè)Runnable參數(shù)給Thread后,Thread的run()方法就會(huì)調(diào)用.run(),參考JDK源代碼:publicvoidrun()if(!=null)}}ExecutorService、Callable、Future實(shí)現(xiàn)有返回結(jié)果的多線(xiàn)程類(lèi)。想要詳細(xì)了解Executor框架的可以http /topic/3691JDK15中引入的新特征,確實(shí)很實(shí)用,有了這種特征我就不需要再為了得到返回值而大費(fèi)周折了,而且即便實(shí)現(xiàn)了也可能??煞祷刂档娜蝿?wù)必須實(shí)現(xiàn)Callable接口,類(lèi)似的,無(wú)返回值的任務(wù)必須Runnable口。執(zhí)行Callable任務(wù)后,可以獲取一個(gè)Future的對(duì)象,在該對(duì)象上調(diào)用get就可以獲取到Callable任務(wù)返回的Object了,再結(jié)合線(xiàn)接口ExecutorService就可以實(shí)現(xiàn)JDK1.5importimportjava.util.concurrent.*;importjava.util.Date;importjava.util.List;importjava.util.ArrayList;Java*@authorpublicclassTest{publicstaticvoidmain(String[]args)throwsExecutionException,InterruptedException{System.out.println("程序開(kāi)始運(yùn) Datedate1=newinttaskSize=ExecutorServicepool=List<Future>list=newfor(inti=0;i<taskSize;i++){Callablec=newMyCallable(i+"");FutureFuturef=//System.out.println(">>>"+f.get().toString());}for(Futuref:list)FutureSystem.out.println(">>>"+}Datedate2=newSystem.out.println("程序結(jié)束運(yùn) ,程序運(yùn)行時(shí)間【+(date2.getTime()-date1.getTime())}}classMyCallableimplementsCallable<Object>{privateStringtaskNum;MyCallable(StringtaskNum){this.taskNum=taskNum;}publicObjectcall()throwsException{System.out.println(">>>"taskNumDatedateTmp1=newDate();DatedateTmp2=newlongtimedateTmp2.getTime()dateTmp1.getTime();System.out.println(">>>"+taskNum+"任務(wù)終止");returntaskNumtime}}上述代碼中Executors類(lèi),提供了一系列工廠(chǎng)方法用于創(chuàng)先線(xiàn),返回的線(xiàn)都實(shí)ExecutoServicepublicstaticExecutorServicenewFixedThreadPool(in創(chuàng)建固定數(shù)目線(xiàn)程的線(xiàn)publicstaticExecutorService創(chuàng)建一個(gè)可緩存的線(xiàn),調(diào)用execute將重用以前構(gòu)造的線(xiàn)程(如果線(xiàn)程可用)。如60publicstaticExecutorService創(chuàng)建一個(gè)單線(xiàn)程化的ExecutorpublicstaticScheduledExecutorServicenewScheduledThreadPool(int創(chuàng)建一個(gè)支持定時(shí)及周期性的任務(wù)執(zhí)行的線(xiàn),多數(shù)情況下可用來(lái)替代Timer類(lèi)ExecutoreServicesubmit()CallableRunnable,返回象的get()方阻塞直到計(jì)算完成。一、多線(xiàn)1、操作系統(tǒng)有兩個(gè)容易的概念,進(jìn)程和線(xiàn)程CPU調(diào)度執(zhí)行的基本單位;線(xiàn)程有自己的程序計(jì)數(shù)器、2、Java標(biāo)準(zhǔn)庫(kù)提供了進(jìn)程和線(xiàn)程相關(guān)的API,進(jìn)程主要包括表示進(jìn)程java.lang.ThreadJavamain方法這、線(xiàn)程間的可見(jiàn)性:一個(gè)線(xiàn)程對(duì)進(jìn)程享的數(shù)據(jù)的修改,是否對(duì)另一個(gè)線(xiàn)程可可見(jiàn)性問(wèn)題:[java]viewplaina、CPU采用時(shí)間片輪轉(zhuǎn)等不同算法來(lái)對(duì)[java]viewplain1.publiccla privateintvalue= publicint }}CPU時(shí)間來(lái)獲取運(yùn)行機(jī)會(huì),CPU切換可能發(fā)生在執(zhí)行間隙。[java]viewplaingetNext()的指令序列:CPU7[java]viewplain.getfield.6.7.putfieldb、CPU緩存CPU一般采用層次結(jié)構(gòu)的多級(jí)緩存的架構(gòu)CPUL1、L2L3三級(jí)緩存。當(dāng)CPU需要主存中某個(gè)位置的數(shù)據(jù)時(shí),會(huì)一次檢查各級(jí)緩存中是否存在對(duì)應(yīng)的數(shù)據(jù)。如果有,直接從緩存中,這比從主存中速度快很多。當(dāng)CPU需要寫(xiě)入c、指令順二、Java內(nèi)存模型(JavaMemory了U元素;關(guān)注線(xiàn)程間的動(dòng)作。1、volatile:用來(lái)對(duì)共享變量的進(jìn)行同步,上一次寫(xiě)入操作的結(jié)果對(duì)下一次讀取操作是肯定可見(jiàn)的。(volatile變量值之后,CPU緩存中的內(nèi)容會(huì)被寫(xiě)回內(nèi)存;在volatile變量時(shí),CPU緩存中的對(duì)應(yīng)內(nèi)容會(huì)被置為失效,重新從主存中進(jìn)行讀取),volatile不使用鎖,性能優(yōu)于synchronized。[java]viewplainpublicclassprivatevolatile[java]viewplainpublicclassprivatevolatilebooleanpublicvoidsetDone(booleanthis.done= publicvoid [java]viewplain例子:錯(cuò)誤使用。因?yàn)闆](méi)有鎖的支持,volatile[java]viewplain1.publicclassCounter publicvolatilestaticintcount= publicvoidinc() 1 try }catch(InterruptedExceptione) publicstaticvoidmain(String[]args) for(inti=0;i<1000;i++) newThread(newRunnable() publicvoidrun() System.out.println("運(yùn)行結(jié)果:Counter.count 2、finalfinal的域的值只能被初始化一次,一般在構(gòu)造方法中初始化(在多線(xiàn)程開(kāi)發(fā)中,final域通常用來(lái)實(shí)現(xiàn)不可變對(duì)象)另外,在代碼執(zhí)行時(shí),final域的值可以被保存在寄存器中,而不用從主存中頻繁重新讀3、java基本類(lèi)型的原子基本類(lèi)型,類(lèi)型的是原子操作;(即一條指令完成long與double的賦值,是可以分割的,非原子操作要程間共享long或double的字段時(shí),必須在synchronized中操作,或是三、Java提供的線(xiàn)程同步方1、synchronized所有的Java對(duì)象都有一個(gè)與synchronzied關(guān)聯(lián)的監(jiān)視器對(duì)象(monitor),允許線(xiàn)該a、靜態(tài)方法:JavaClassc、代碼塊:代碼塊中的對(duì)象所關(guān)聯(lián)的監(jiān)視器對(duì)象注:當(dāng)鎖被,對(duì)共享變量的修改會(huì)寫(xiě)入主存;當(dāng)活得鎖,CPU緩存中的內(nèi)容被置為無(wú)synchronized方法或代碼塊,不會(huì)把其中包含的代碼移動(dòng)到synchronized方法或代碼塊之外,從而避免了由于代碼重排而造成的問(wèn)題。[java]viewplain1.[java]viewplain1.publicclasspublicsynchronizedint}} returnpublicintreturnprivateintvalue=2、Objectwait、notifynotifyAll方whilevolatileCPU時(shí)間,對(duì)性能造waitABwait()A進(jìn)入B對(duì)象的等待池,并且B的鎖。(這里,線(xiàn)程A必須持有B的鎖,所以調(diào)用的synchronizedjava.lang.IllegalMonitorStateException放掉鎖,鎖池中的線(xiàn)程即可競(jìng)爭(zhēng)對(duì)象的鎖來(lái)獲得執(zhí)行機(jī)會(huì)。(notify鎖喚醒的線(xiàn)程選擇由虛擬機(jī)實(shí)現(xiàn)來(lái)決定,不能保證一個(gè)對(duì)象鎖關(guān)聯(lián)的等待集合中notifyAll方法,不過(guò)該方導(dǎo)致線(xiàn)沒(méi)有必要的情況下被喚醒,之后又馬上進(jìn)入等待池,對(duì)性能有影a、ConsumerAwait()A進(jìn)入產(chǎn)b、ProducerBnotifyAll(),ConsumerA從產(chǎn)品的等待池進(jìn)入鎖池,Producer線(xiàn)程B生產(chǎn)產(chǎn)品,然后退出鎖。[java]viewplainc、Consumer[java]viewplain1.publicsynchronizedString this.notifyAll喚醒對(duì)象等待池中的所有線(xiàn)程,可能喚醒的就是生產(chǎn)者(發(fā)現(xiàn)產(chǎn)品滿(mǎn),就會(huì)進(jìn)入對(duì)象的等待池,這里代碼省略,基本略同 while(index==-1){//如果發(fā)現(xiàn)沒(méi)產(chǎn)品,就鎖,進(jìn)入對(duì)象等待 當(dāng)生產(chǎn)者生產(chǎn)完后,消費(fèi)者從一產(chǎn)品還是為空,則再等待,所以這里必須用while循環(huán),不能用 Stringgood= buffer[index]= returngood3、線(xiàn)程狀態(tài)轉(zhuǎn)換已經(jīng)廢棄的方法:st、sus、rsume、stroy、E、BLOKE、WAITITIMED_AITIN(有超時(shí)a、方法sleep()進(jìn)入的阻塞狀態(tài),不會(huì)對(duì)象的鎖(即大家,誰(shuí)也別想執(zhí)行代碼),sleepsynchronized方法或代碼塊中,否則造成其他等待獲取bjoin()main[java]view[java]viewplain2.Threadt1=newThread(new1.publicstatic2.Threadt1=newThread(new3.Threadt2=newThread(new.t1.join等t16.7.t2.join8.8.cinterrupt()ABd的interruptB來(lái)處理這個(gè)請(qǐng)求,當(dāng)然也可以忽略,這不是必須的。Objectwait()、Threadjoin()sleep方法都會(huì)拋出受檢異常java.lang.InterruptedExceptioninterrupt方法中斷該線(xiàn)程會(huì)導(dǎo)致線(xiàn)程離開(kāi)等待狀I(lǐng)nterruptedException異常,并致以異常的處理邏輯。ThreadisInterrupted方法來(lái)判斷是否有中斷請(qǐng)求發(fā)生,通??梢岳眠@個(gè)方法來(lái)判斷是否退出線(xiàn)程(volatitle修飾符的例子);ThreadInterrupted(),該方法不但可以判斷當(dāng)前線(xiàn)程是否被中斷,還會(huì)清楚線(xiàn)程的中斷標(biāo)記,如果返回true,即曾被請(qǐng)求中斷,同時(shí)調(diào)用完后,清除中斷標(biāo)記。如果一個(gè)線(xiàn)某個(gè)對(duì)象的等待池,那么notify和interrupt都可以使該線(xiàn)程從等待池中被notify先,那照常喚醒,沒(méi)影響。如interruptnofity,也會(huì)忽略該線(xiàn)程,而e、yield()CPU資源,讓其他線(xiàn)程獲取運(yùn)行機(jī)會(huì),對(duì)操作系統(tǒng)上的調(diào)度器來(lái)說(shuō)是一個(gè)信號(hào),不一定立即切換線(xiàn)程。(yeid方四、非阻塞方線(xiàn)程之間同步機(jī)制的是監(jiān)視對(duì)象上的鎖,競(jìng)爭(zhēng)鎖來(lái)獲得執(zhí)行代碼的機(jī)會(huì)。當(dāng)一個(gè)對(duì)象程度限制了多線(xiàn)程程序的吞吐量和性能(線(xiàn)程阻塞),且會(huì)帶來(lái)死鎖(A有a對(duì)象bB有ba對(duì)象鎖)和優(yōu)先級(jí)倒置(優(yōu)先級(jí)CPU本身實(shí)現(xiàn)將這三步合起來(lái)形成一個(gè)原子操作,無(wú)需線(xiàn)程鎖機(jī)制干預(yù),常見(jiàn)的指令是“比較和替換”(compareandswap,CAS),這個(gè)指令會(huì)先比較某個(gè)內(nèi)存地址的當(dāng)前CASCASCAS指令成功完成修改。java.util.concurrent.atomicCAS指令。(CPUCAS,在某些平臺(tái),java.util.concurrent.atomic的實(shí)現(xiàn)仍然是鎖機(jī)制)atomic包中提供的Java類(lèi)分成三類(lèi)1、支持以原子操作來(lái)進(jìn)行更新的數(shù)據(jù)類(lèi)型Java類(lèi)(AtomicBoolean、AtomicInteger、AtomicReference),volatile變量。 pareAndSet:效果同compareAndSet(JSR中表示weak原子方式和有條件地寫(xiě)入變量但不創(chuàng)建任何happen-before排序,但在源代碼中和compareAndSet完全一樣,所以并沒(méi)有按JSR實(shí)現(xiàn))c、getsetd、lazySetsetlazySet方法的調(diào)用與后面的指令進(jìn)行重排,因[java][java]viewplain1.publicclass privatefinalAtomicIntercounter=new publicint }}7.7.//getAndIncrement方法 intnext=currentreturn intcurrent=8.publicfinalintaomiaymicLong和ominy(素索引的參數(shù))[java]viewplain3、通過(guò)反射的方式對(duì)任何對(duì)象中包volatitle變量使CAS方法,他們提供了式把CAS的功能擴(kuò)展到了任何Java類(lèi)中為volatitle的域上。(靈[java]viewplain1.publicclass privatevolatileTreeNode3.// privatestaticfinalAtomicReferenceFieldUpdater<TreeNode,TreeNode>parentUpdater=5.publicbooleancompareAndSetParent(TreeNodeexpect,TreeNode pareAndSet(this,expect,7.8.java.util.concurrent.atomic包中的Java類(lèi)屬于比較底層的實(shí)現(xiàn),一般作為AtomicBoolean、AtomicInteger、AtomicLongAtomicReference。在實(shí)現(xiàn)線(xiàn)程安全的計(jì)數(shù)器時(shí),AtomicIntegerAtomicLong類(lèi)時(shí)最佳的選擇。五、高級(jí)同步機(jī)制(synchronized更靈活的加鎖synchronizedvolatilewait、notify等方法抽象層次低,在程序開(kāi)發(fā)中使用比較繁這些模式抽象成API,使用起來(lái)會(huì)非常方便。java.util.concurrent包為多線(xiàn)程提供了的API,滿(mǎn)足日常開(kāi)發(fā)中的常見(jiàn)需求。1、Lock接口,表示一個(gè)鎖方法b、unlock(),鎖。(一般放在finally代碼塊中)(d、tryLock()false。(tryLock()的另一2、ReadWriock接口,表示兩個(gè)鎖,的共享鎖和寫(xiě)入的排他鎖。(適合常見(jiàn)的讀ReadWriockreadLockwriockLock接口的實(shí)現(xiàn)。3、ReentrantLock類(lèi)和ReentrantReadWriock,分別為上面兩個(gè)接口的實(shí)現(xiàn)類(lèi)。[java]viewplain同一個(gè)線(xiàn)程每次獲取鎖,加鎖數(shù)+1,每次鎖,加鎖數(shù)-1,到0[java]viewplain1.publicclass2.//newReentrantLock(true)是重載,使用更加公平的加鎖機(jī)制,在鎖被后,會(huì)優(yōu)先給 privateintReentrantLocklock= privafteintvalue= publicint returnvalue++;// shMapxt(鎖之后可以保證一個(gè)線(xiàn)程一口氣完成便利而不會(huì)每次xt(之后鎖然后和(成任務(wù),再把鎖傳遞給其他線(xiàn)程。注:與Object類(lèi)的wait()相同,await()會(huì)其所持有的鎖[java]viewplaine、signal()[java]viewplain1.Locklock=new2.Conditioncondition=3.4. 8. 六、底層同步Java標(biāo)準(zhǔn)庫(kù)提供的同步方式之外,程序中特有的同步方式需要由開(kāi)發(fā)自己來(lái)實(shí)現(xiàn)。常見(jiàn)的一種需求是對(duì)有限個(gè)共享資源的,比如多臺(tái)個(gè)人電腦,2臺(tái),當(dāng)多個(gè)線(xiàn)FIFO隊(duì)列。如果程序中的同步方式可以抽象成對(duì)有限個(gè)資源的,那么可以使 QueuedLongSynchronizerint類(lèi)型的變量來(lái)long類(lèi)型。(可以將這個(gè)變量理解為共享資源個(gè)數(shù))通過(guò) 、 pareAndSetState3個(gè)方法更新變量的值compareAndSetState3[java]viewplain1.publicclassprivatestaticclassInnerSynchronizer{protectedinttryAcquireShared(intintavailablecompareAndSetState3[java]viewplain1.publicclassprivatestaticclassInnerSynchronizer{protectedinttryAcquireShared(intintavailable=if(remain<0||comapreAndSetState(available,}}intnext=available+return} synchronizer=new publicvoidacquire()throws pubicvoid publicSimpleResourceManager(int}}intavailable=protectedbooleantryReleaseShared(int}returnintremain=available-}InnerSynchronizer(intprivatefinalInnerSynchronizer}七、高級(jí)同步對(duì)象(提高開(kāi)發(fā)效率atomic和locks包提供的Java類(lèi)可以滿(mǎn)足基本的互斥和同步的需求,但這些Java類(lèi)1、信號(hào)量在使用資源時(shí),需要從該信號(hào)量上獲取,成功獲取,資源的可用數(shù)-1;完成對(duì)資源的使用,,資源可用數(shù)+1;當(dāng)資源數(shù)為0時(shí),需要獲取資源的線(xiàn)程以阻塞的SimpleResourceManager類(lèi)實(shí)際上時(shí)信號(hào)量的一個(gè)簡(jiǎn)單實(shí)現(xiàn))java.util.concurrent.SemaphoreSemaphore類(lèi)的對(duì)象時(shí)指定資源的可用數(shù)b、tryAcquire(),以非阻塞方式獲取[java]viewplaind、accquireUninterruptibly(),[java]viewplain1.1.publicclassprivatefinalList<Printer>printers=newthis.semaphore=newpublicPrinteracquirePrinter()throwsreturn publicvoidreleasePrinter(Printer privatesynchronizedPrinter }publicPrinterManager(Collection<?extendsPrinter>privatefinalSemphore printerresult= return privatesynchronizedvoidputBackPrinter(Printer 2、倒數(shù)java.util.concurrent.CountDownLatch類(lèi),創(chuàng)建該類(lèi)時(shí),指定等待完成的任務(wù)數(shù);當(dāng)一個(gè)態(tài),直到任務(wù)數(shù)量為0。CountDownLatch類(lèi)為,一旦任務(wù)數(shù)為0,再調(diào)用await()[java][java]viewplain1.publicclass 并發(fā)性能遠(yuǎn)遠(yuǎn)優(yōu)于HashTable的Map實(shí)現(xiàn),hashTable做任何操作都需要獲得鎖,同一時(shí)間只有有個(gè)線(xiàn)程能使用,而ConcurrentHashMap是分段加鎖,不同線(xiàn)程不同的數(shù)據(jù)段,完全不受影響,忘記HashTable privatestaticfinalConcurrentHashMap<String,Interger>sizeMap=new privatestaticclassGetSizeWorkerimplements privatefinalString publicGetSizeWorker(StringurlString,CountDownLatch this.urlString= this.signal= publicvoid InputStreamis=new intsize= sizeMap.put(urlString, }catch(IOException sizeMap.put(urlString,- signal.countDown()://完成一個(gè)任務(wù),任務(wù)數(shù)- privatevoid List<Entry<String,Integer>list=new Collections.slort(list,new publicintcompare(Entry<String,Integer>o1,Entry<Sting,r> publicvoidsortPageSize(Collection<String>urls)throws CountDownLatchsortSignal=new for(Stringurl: newThread(newGetSizeWorker(url, 3、循環(huán)屏循環(huán)屏障在作用上類(lèi)似倒數(shù),不過(guò)他不像倒數(shù)是的,可以循環(huán)使用。另java.uti.concurrent.CyclicBarrier用來(lái)表示循環(huán)屏障,創(chuàng)建時(shí)指定使用該對(duì)象的線(xiàn)程數(shù)Runnable接口的對(duì)象作為每次循環(huán)后執(zhí)行的動(dòng)作。(當(dāng)最后一個(gè)線(xiàn)Runnalbe接口的對(duì)象來(lái)處理)。awaitawait方法之[java]view[java]viewplain1.publicclassPriprivatestaticfinalintTOTAL_COUTN=privatestaticfinalintRANGE_LENGTH=privatestaticfinalintWORKER_NUMBER=privatestaticvolatitlebooleandone=privatestaticintrangeCount=privatestaticfinalList<Long>results=new privatestaticfinalCyclicBarrierbarrier=newCyclicBarrier(WORKER_NUMBER,newRunnable(){publicvoidif(results.size()>=done= privatestaticclassPrimeFinderimplementspublicvoid while(!done){//整個(gè)過(guò)一個(gè)while循環(huán)下,await()等待,下次循環(huán)開(kāi)始,會(huì)再次判斷執(zhí)行條件intrange=longstart=rang*longend=(range+1)*for(longi=start;}}}catch(InterruptedException|done=}}}}privatesynchronizedstaticvoidupdateResult(long}privatesynchronizedstaticintreturn}privatestaticbooleanisPrime(long}publicvoid for(int newThread(new 4、對(duì)象交換適合于兩個(gè)線(xiàn)程需要進(jìn)行的場(chǎng)景(一個(gè)線(xiàn)程完成后,把結(jié)果交給另一個(gè)線(xiàn)程繼續(xù)icurrent.Exchar類(lèi),提供了這種對(duì)象交換能力,兩個(gè)線(xiàn)程共個(gè)ExchanrExchar類(lèi)的c)ce方法的返回結(jié)果是另外一個(gè)線(xiàn)程鎖提供的相同類(lèi)型的對(duì)象。如果另外一個(gè)線(xiàn)程未完成對(duì)數(shù)據(jù)的處gc方法來(lái)進(jìn)行。[java]view[java]viewplainpublicclass privatefinalExchanger<StringBuilder>exchanger=newExchanger<StringBuprivateclassSenderimplementspublicvoidStringBuildercontent=newcontent=}catch(InterruptedException}}}privateclassReceiverimplementspublicvoidStringBuildercontent=newcontent=}catch(InterruptedException publicvoid newThread(new newThread(new 八、數(shù)據(jù)結(jié)構(gòu)(多線(xiàn)程程序使用的高性能數(shù)據(jù)結(jié)構(gòu)java.util.concurrent包中提供了一些適合多線(xiàn)程程序使用的高性能數(shù)據(jù)結(jié)構(gòu),包括隊(duì)列和1、隊(duì)a、BlockingQueue接口:線(xiàn)程安全的阻塞式隊(duì)列;當(dāng)隊(duì)列已滿(mǎn)時(shí),想隊(duì)列添加會(huì)阻塞;ArrayBolockingQueue和基于鏈表結(jié)構(gòu)的不固定元LinkedBlockQueue類(lèi)。b、BlockingDeque接口BlockingQueue相似,但可以對(duì)頭尾進(jìn)行添加和刪除操作java.util包中的集合a、ConcurrentMap接口java.util.Map接口replace(key,value)valuekey上。replace(key,oldvalue,newvalue):CAS的實(shí)現(xiàn)。HashMap也一樣,只是多線(xiàn)程下更耗時(shí))。創(chuàng)建時(shí),預(yù)估進(jìn)行更新操作的線(xiàn)程數(shù),這樣實(shí)現(xiàn)中會(huì)根據(jù)這個(gè)數(shù)把空間劃分為對(duì)應(yīng)數(shù)量的部分。(默認(rèn)是,如果只有一個(gè)線(xiàn)程進(jìn)行寫(xiě)操作,其他都是,那么把值設(shè)為1可以提高性能)。Map元素時(shí),不一定能看到正在添加的數(shù)據(jù),只能和集合保證弱一致性。(Map,而拋出CopyOnWriteArrayList的實(shí)現(xiàn)類(lèi),所有對(duì)列表的更新操作都會(huì)新創(chuàng)建一個(gè)底九、多線(xiàn)程任務(wù)的執(zhí)過(guò)去線(xiàn)程的執(zhí)行,是先創(chuàng)建Thread類(lèi)的想,再調(diào)用start方法啟動(dòng),這種做法要求開(kāi)發(fā)人J2SE5.0中,java.util.concurrent1、基本接口(描述任務(wù)a、CallableRunnable接口受限于run方法的類(lèi)型簽名,而Callable只有一個(gè)方法call(),可以有返回b、FutureFutureget()方法可以獲取異步的c、Delayed接口:2、組合接口(描述任務(wù)a、RunnableFutureRunnableFuture當(dāng)來(lái)自Runnalbe接口中的run方法成功執(zhí)行之后,相當(dāng)于Future接口表示的異步任務(wù)已get()獲取運(yùn)行結(jié)果。b、ScheduledFutureFutureDelayed接口,表示一個(gè)可以調(diào)用的異步c、RunnableScheduledFutureRunnable、DelayedFuture,接口中包含3、Executor接口、ExcutorServer接口、ScheduleExecutorService接口CompletionService接口(描述任務(wù)執(zhí)行b、excutorServerFuture提供批量執(zhí)行:kk)a;k),會(huì)等待Future的列表;k),任何一個(gè)任務(wù)成功完成,即返回該任務(wù)結(jié)果。c、ScheduleExecutorServiceexcutorServer接口:支持任務(wù)的延遲執(zhí)行和CallableRunnable。ScheduledFutured、CompletionServiceExecutorServicesubmitFuture接口來(lái)獲Future在CompletionService就是解決這個(gè)問(wèn)題,程序不同部分可以共享CompletionServicetake(阻塞),poll(非阻塞)來(lái)獲[java]viewplain pletionService,在創(chuàng)建時(shí),需要提供一個(gè)Executor接[java]viewplain privatefinalExecutorServiceexecutor privatefinalExecutorServiceexecutor=;publicbooleandownload(finalURLurl,finalPath // Future<Pathfutureexecutor.submit(newCallable<Pathsubmit提交 publicPath InputStreamis= Files.copy(is,path, return returnfuture.get()!=null?true: }<spanstyle="font-family:Arial,Helvetica,serif;">catch(InterruptedException|ExecutionException return publicvoidclose(){//FileDownloader類(lèi)的對(duì)象時(shí),應(yīng)該使用close方法關(guān)閉其中包含的ExecutorService接口的實(shí)現(xiàn)對(duì)象,否則虛擬機(jī)不會(huì)退出,占用內(nèi)存不釋放 executor.shutdown if(!executor.awaitTermination(3,TimeUnit.MINUTES)){//tion executor.shutdownNow束 executor.awaitTermination(1,TimeUnit.MINUTES }catch(InterruptedException 十、JavaSE7java.util.concurrentfork/join和多階段線(xiàn)1、輕量級(jí)任務(wù)執(zhí)行框架map/reduce算法來(lái)解決問(wèn)題。fork/joinmap/reducefork操作是把一個(gè)大的問(wèn)題劃分為若干個(gè)較小的問(wèn)題,劃分過(guò)程一般為遞歸,直到可以直join相對(duì)一般的線(xiàn)實(shí)現(xiàn),F(xiàn)/J框架的優(yōu)勢(shì)在任務(wù)的處理方式上。在一般線(xiàn)中,一個(gè)線(xiàn)F/J,某個(gè)子問(wèn)題由于等待另外一個(gè)子問(wèn)題的完為了F/J能高效,在每個(gè)子問(wèn)題視線(xiàn)中應(yīng)避免使用synchronized或其他方式進(jìn)行同步,也不應(yīng)使用阻塞式IO或過(guò)多共享變量。在理想情況下,每個(gè)子問(wèn)題都應(yīng)值進(jìn)行CPU計(jì)算,只使用每個(gè)問(wèn)題的對(duì)象,唯一的同步應(yīng)只發(fā)生在子問(wèn)題和創(chuàng)建它的父問(wèn)題之間。(HadoopMapReduce嘛a、ForkJoinTask類(lèi)F/JFuture接口,可以Future接口的方式來(lái)使用。(表示任務(wù))RecuriveTaskRecursiveAction,前者可以返回結(jié)果,后者不行。b、ForkJoinPool類(lèi)ExecutorServiceForkJoinTaskCallableRunnable。(任務(wù)執(zhí)行)第一類(lèi):execute、invokesubmit方法:直接提交任務(wù)。第二類(lèi):fork()ForkJoinTask在執(zhí)行過(guò)程中的子任務(wù)。ForkJoinTask用第一類(lèi)提交,執(zhí)行過(guò)程中產(chǎn)生的子任務(wù)不需要處理,F(xiàn)orkJoinPool會(huì)負(fù)責(zé)子任務(wù)執(zhí)行。[java][java]viewplain1.privatestaticclassMaxValueTaskextends privatefinallong[] privatefinalint privatefinalint MaxValueTask(long[]array,intstart,int this.array= this.start= this.end= pute是RecursiveTask protectedlongif(endstartRANG_LENGTH){//if(array[i]>}}elseMaxValueTasklowTask=newMaxValueTask(array,start,lowTask.forkmaxMath.max(max,lowTask.join());//} MaxValueTasktask=newMaxValueTask(array,0,return Longresult= publicLong ong[]returnmax=Math.max(max,MaxValueTaskhighTask=newMaxValueTask(array,mid,intmid=(start+end)}max=for(inti=start;longmax=在實(shí)際中,F(xiàn)/J框架發(fā)揮作用的場(chǎng)合很多,比如在一個(gè) F/J2、多階段線(xiàn)程同步工Phaser類(lèi)是JavaSE7中新增的一個(gè)使用同步工具,功能和靈活性比倒數(shù)和循環(huán)屏障F/JPhaserPhaser把多個(gè)線(xiàn)程寫(xiě)作執(zhí)行的任務(wù)劃分成多個(gè)階段(phase),編程時(shí)要明確各個(gè)階段的任務(wù),每個(gè)階段都可以有任意個(gè)參與者,線(xiàn)程可以隨時(shí)并參與到某個(gè)階段,當(dāng)一個(gè)階段中所有線(xiàn)程都成功完成之后,PhaseronAdvance()被調(diào)用,可以通過(guò)覆蓋添加自定義處理邏輯(Runnable接口),Phaser類(lèi)會(huì)自動(dòng)進(jìn)入下個(gè)階Phaser不再包含任何參與者。Phaser創(chuàng)建后,初始階段為0,構(gòu)造函數(shù)中指定初始參與個(gè)數(shù)arriveAndDeregister(),任務(wù)完成,取消自己的。arriveAndAwaitAdvance()Phaser成awaitAdvance()、awaitAdvanceInterruptibly()phaser進(jìn)入下個(gè)階段,參數(shù)為當(dāng)前階段的,后者可以設(shè)置超時(shí)和處理中斷請(qǐng)求。來(lái)指定當(dāng)前對(duì)象的父對(duì)象;當(dāng)一個(gè)子對(duì)象參與者>0,會(huì)自動(dòng)到父對(duì)象中;當(dāng)=0,自動(dòng)解除。例:從指定,img的階段1、處理對(duì)應(yīng)的html文本,和抽取img的;2、創(chuàng)建子線(xiàn)程,主[java]viewplainpublicclass privatefinalPhaserphasernewPhaser(1);//1publicvoiddownload(URLurl,finalPathpath)throwsStringcontentgetContent(url);//HTMLList<URL>imageUrls=extractImageUrls(content);//獲 ,省略for(finalURLimageUrl:newpublicvoid InputStreamis= File.copy(is,getSavePath(path,imageUrl),StandardCopyOpt}catch(IOException 線(xiàn)程一個(gè)ThreadLocal類(lèi)的對(duì)象時(shí),鎖和修改的事每個(gè)線(xiàn)程變量各自獨(dú)立的對(duì)ThreadLocal可以快速把一個(gè)非線(xiàn)程安全的對(duì)象轉(zhuǎn)換成線(xiàn)程安全的對(duì)象。(同時(shí)c、initialValue()setget,會(huì)通過(guò)initValue來(lái)獲取對(duì)象的初始值。[java]viewplainThreadLoacl的一般用法,創(chuàng)建一個(gè)ThreadLocal的子類(lèi)并覆蓋[java]viewplainpublicclass privatefinalThreadLocal<IdGenerator>idGeneratornew getNext(){new} publicstaticint return}ThreadLocal中。java.util.Random會(huì)帶來(lái)競(jìng)爭(zhēng)問(wèn)題,java.util.concurrent.ThreadLocalRandom類(lèi)提供多線(xiàn)ThreadLoacl??偨Y(jié):多線(xiàn)程開(kāi)發(fā)中應(yīng)該優(yōu)先使用API,如果,使用java.util.concurrent.atomicjava.util.concurrent.locks包提供的APIsynchronizedvolatile,以wait,notify和notifyAll等低API應(yīng)該最后考慮。Java線(xiàn)程:概念與原一、操作系統(tǒng)中線(xiàn)程和進(jìn)程的概以啟動(dòng)多個(gè)線(xiàn)程。比如在Windowsexe就是一個(gè)進(jìn)程。java.exe進(jìn)程中可以運(yùn)二、Java中的線(xiàn)1、java.lang.Threadjava.lang.Threadjava.lang.RunnableThreadJava中的任何其他對(duì)象一樣,具有變量和方法,生死于Java中,每個(gè)線(xiàn)程都有一個(gè)調(diào)用棧,即使不在程序中創(chuàng)建任何新的線(xiàn)程,線(xiàn)程也在運(yùn)行當(dāng)所有用戶(hù)線(xiàn)程執(zhí)行完畢的時(shí)候,JVMJVM,守候線(xiàn)程一Java線(xiàn)程:創(chuàng)建與啟一、定義線(xiàn)1java.lang.ThreadpublicpublicvoidRunnableRunnablerun方法;否Thread2java.lang.RunnablevoidRunnable的對(duì)象創(chuàng)建一個(gè)線(xiàn)程時(shí),啟動(dòng)該線(xiàn)程將導(dǎo)致在獨(dú)立執(zhí)行的線(xiàn)程中調(diào)用對(duì)run方法。二、實(shí)例化線(xiàn)1java.lang.Thread類(lèi)的線(xiàn)程,則直接new2java.lang.RunnableThreadThread(Runnable)Thread(Runnable,Stringname)Thread(ThreadGroupgroup,Runnable)Thread(ThreadGroupgroup,Runnable,Stringname)Thread(ThreadGroupgroup,Runnable,Stringname,long三、啟動(dòng)線(xiàn)在調(diào)用rt(Tred當(dāng)該線(xiàn)程獲得機(jī)會(huì)執(zhí)行時(shí),其目標(biāo)run()vaun(mai)unnblehredn四、例1Runnable*Runnable***@authorleizhimin2008-9-13publicclassDoSomethingimplementsRunnable{privateStringname;publicDoSomething(Stringname){thisname=name;}publicvoidrun()for(inti=0;i<5;i++)for(longk=0;k<100000000;k++);System.out.println(name+":"+i);}}}Runnable*@authorleizhimin2008-9-13publicclassTestRunnable{publicstaticvoidmain(String[]args){DoSomethingds1newDoSomething("阿三DoSomethingds2=new Threadt1=newThread(ds1);Threadt2=newThread(ds2);}}::阿三::阿三::::阿三::阿三:阿三:Processfinishedwithexitcode2Thread*@authorleizhimin2008-9-13publicclassTestThreadextendsThread{publicTestThread(Stringname){}publicvoidrun()for(inti=for(longk=0;k<100000000;k++);}}publicstaticvoidmain(String[]args)Threadt1newTestThread("阿三");Threadt2newTestThread("");}}Processfinishedwithexitcodefor(longk=0;五、一些常見(jiàn)mian,非主線(xiàn)程的名字不確定。7JVMCPU的機(jī)器上上,實(shí)際上一次只能運(yùn)行一個(gè)線(xiàn)程。一次只有一個(gè)線(xiàn)程棧執(zhí)行。JVM線(xiàn)程調(diào)度程序決定實(shí)際運(yùn)行哪個(gè)處于可運(yùn)行狀態(tài)的線(xiàn)程。Java線(xiàn)程:線(xiàn)程棧模型與線(xiàn)程的變當(dāng)程序執(zhí)行到t.start();時(shí)候,程序多出一個(gè)分支(增加了一個(gè)調(diào)用棧B),這樣,棧A、棧B并Java線(xiàn)程:線(xiàn)程狀態(tài)的轉(zhuǎn)5、態(tài):當(dāng)線(xiàn)程的run()方法完成時(shí)就認(rèn)為它死去。這個(gè)線(xiàn)程對(duì)象也許是活的,但是,它已start()方拋出java.lang.IllegalThreadStateException異常。對(duì)于線(xiàn)程的,考慮一下三個(gè)方面,不考慮IO阻塞的情況:Thread.sleep(longmillis)和Thread.sleep(longmillis,intnanos)靜態(tài)方法強(qiáng)制當(dāng)前正在執(zhí)行的線(xiàn)程Java規(guī)范不保證合理的輪try}catch(InterruptedExceptione){}例如 publicvoidrun()for(inti= for(longk=0;ktry}catch(InterruptedExceptione){e.printStackTrace();.}}}Processfinishedwithexitcode*100110***@authorleizhimin2008-9-14publicclassMyThreadextendsThreadpublicvoidrun()for(inti=0;i<100;i++){if((i)%10==0){ "+}try{ }catch(InterruptedExceptione){}}}publicstaticvoidmain(String[]args){newMyThread().start();}}0111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111Processfinishedwithexitcode要理解yield()1~10之間。JVM線(xiàn)程調(diào)度程序是基于優(yōu)先級(jí)的搶先調(diào)度機(jī)制。在大多數(shù)情況下,當(dāng)前運(yùn)行的線(xiàn)程優(yōu)先當(dāng)線(xiàn)中線(xiàn)程都具有相同的優(yōu)先級(jí),調(diào)度程序的JVM實(shí)現(xiàn)它喜歡的線(xiàn)程。這時(shí)候調(diào)Threadt=newMyThread();1~10之間的正整數(shù),JVM從不會(huì)改變一個(gè)線(xiàn)程的優(yōu)先級(jí)。然而,1~10之間的值并,變成少于10個(gè)的優(yōu)先級(jí),則兩個(gè)或多個(gè)優(yōu)先級(jí)的線(xiàn)程可能被為一個(gè)優(yōu)先級(jí)。staticintstaticintstaticint行機(jī)會(huì)。因此,使用yield()的目的是讓相同優(yōu)先級(jí)的線(xiàn)程之間能適當(dāng)?shù)妮嗈D(zhuǎn)執(zhí)行。但是,實(shí)際中無(wú)法保證yield()達(dá)到讓步目的,因?yàn)樽尣降木€(xiàn)程還有可能被線(xiàn)程調(diào)度程序再次選中。Threadjoin()B“加入”A的尾部。在A執(zhí)行完畢之前,B不能工作。例如:Threadt=newMyThread();另外,join()t.join(5000);5000毫秒,如果1、線(xiàn)程的run()Java線(xiàn)程:線(xiàn)程的同步與一、同步問(wèn)題ThreadA、ThreadBFooFoopublicclassFoo{privateintpublicclassFoo{privateintx=100;publicintgetX()return}publicintfix(inty)x=x-y;returnx;}}publicclasspublicclassMyRunnableimplementsRunnable{privateFoofoo=newFoo();publicstaticvoidmain(String[]args){MyRunnabler=newMyRunnable();Threadta=newThread(r,"Thread-A");Threadtb=newThread(r,"Thread-}publicvoidrun()for(inti=0;i<3;i++){try}catch(InterruptedExceptione){}System.out.println(Thread.currentThread().getName()foo對(duì)象的x值}}publicintfix(inty)returnfoo}}Thread-AThread-Afoo對(duì)象的x值=40Thread-Bfoo對(duì)象的x值=40Thread-Bfoo對(duì)象的x值20Thread-Afoo對(duì)象的x值50Thread-Afoo對(duì)象的x值80Thread-Bfoo對(duì)象的x值Processfinishedwithexitcode從結(jié)果發(fā)現(xiàn),這樣的輸出值明顯是不合理的。原因是兩個(gè)線(xiàn)程不加控制的Foo對(duì)象并修改如果要保持結(jié)果的合理性,只需要達(dá)到一個(gè)目的,就是將對(duì)Foo的加以限制,每次只能有一個(gè)線(xiàn)。這樣就能保證Foo對(duì)象中數(shù)據(jù)的合理性了。Java代碼中需要完成一下兩個(gè)操作:把競(jìng)爭(zhēng)的資源類(lèi)Foo變量x標(biāo)識(shí)為private;二、同步和鎖Java(this實(shí)例)有關(guān)的鎖。獲得一個(gè)對(duì)象的鎖也稱(chēng)為獲取鎖、鎖定對(duì)象、在對(duì)象上鎖定或在對(duì)象個(gè)線(xiàn)程(或返回)鎖。這也意味著任何其他線(xiàn)程都不能進(jìn)入該對(duì)象上的synchronized方法synchronized方法,并且兩個(gè)線(xiàn)程使用相同的實(shí)例來(lái)調(diào)用publicintfix(inty)synchronized(this){x=x-y;}return}publicsynchronizedintgetX(){returnx++;}與publicintgetX()synchronized(this){returnx;}}三、靜態(tài)方法publicstaticsynchronizedintsetName(Stringname){Xxxname=name;}publicstaticintsetName(Stringname){X=}}四、如果線(xiàn)程不能不能獲得鎖會(huì)怎3、靜態(tài)同步方法和非靜態(tài)同步方法將不會(huì)彼此阻塞,因?yàn)殪o態(tài)方法鎖定在Class對(duì)象上,4、對(duì)于同步代碼塊,要看清楚什么對(duì)象已經(jīng)用于鎖定(synchronized后面括號(hào)的內(nèi)容)。在同五、何時(shí)需要SJCP考試范圍了。六、線(xiàn)程安全publicclasspublicclassNameList istnameList=Collections.synchronizedList(newpublicvoidadd(Stringname){}publicString ()if(nameList.size()>0)return(String)}else}}}publicclasspublicclassTestpublicstaticvoidmain(String[]args){finalNameListnl=newNameList();classNameDropperextendsThread{publicvoidrun(){Stringname=nl.remove }}Threadt1=newNameDropper();ThreadThreadt1=newNameDropper();Threadt2=newNameDropper();}}privaistnameList=Collections.synchronizedList(newpublicclasspublicclassNameList istnameList=Collections.synchronizedList(newpublicsynchronizedvoidadd(Stringname){}publicsynchronizedStringremove (){if(nameList.size()>0){return(String)}else}}}七、線(xiàn)程死死鎖對(duì)Java程序來(lái)說(shuō),是很復(fù)雜的,也很難發(fā)現(xiàn)問(wèn)題。當(dāng)兩個(gè)線(xiàn)程被阻塞,每個(gè)線(xiàn)等待另publicclassDeadlockRisk{privatestaticclasspublicclassDeadlockRisk{privatestaticclassResource{publicint}privateResourceresourceA=newResource();privateResourceresourceB=newpublicintread()synchronized(resourceA){synchronized(resourceB){returnresourceB.value+}}}publicvoidwrite(inta,intb){synchronized(resourceB){synchronized(resourceA){resourceA.value=a;resourceB.value=}}}}實(shí)際上,上面這個(gè)例子發(fā)生死鎖的概率很小。因?yàn)樵诖a內(nèi)的某個(gè)點(diǎn),CPU必須從讀線(xiàn)程切換SCJP的考試范圍。八、線(xiàn)程同步Java線(xiàn)程:線(xiàn)程的交線(xiàn)程交互是比較復(fù)雜的問(wèn)題,SCJP要求不很基礎(chǔ):給定一個(gè)場(chǎng)景,編寫(xiě)代碼來(lái)恰當(dāng)使用等待、SCJPjava.lang.Objectvoidvoidvoidnotify()方法或notifyAll()voidwait(longnotify()方法或notifyAll()方法,或者超voidwait(longtimeout,intnotify()方法或notifyAll()方法,或者其wait()、notify()、notifyAll()Object的實(shí)例方法。與每個(gè)對(duì)象具有鎖一樣,每個(gè)對(duì)象可以有一個(gè)線(xiàn)程列表,他們等待來(lái)自該信號(hào)(通知)wait()方法獲得這個(gè)等待列表。從那時(shí)候起,它不再執(zhí)行任何其他指令,直到調(diào)用對(duì)象的notify()方法為止。如果多個(gè)*@authorleizhimin2008-9-15publicclassThreadApublicstaticvoidmain(String[]args){ThreadBb=newThreadB();//A擁有bwait()notify()方法,該線(xiàn)程必須是那個(gè)對(duì)象synchronized(b)try//A}catch(InterruptedExceptione){}System.out.println("b對(duì)象計(jì)算的總和是:}}}*1+2+3100***@authorleizhimin2008-9-15publicclassThreadBextendsThread{inttotal;publicvoidrun()synchronized(this)for(inti=0;i<101;i++){total+=i;}}}}等待對(duì)象等待對(duì)象bbProcessfinishedwithexitcode)noty()時(shí),并意著這時(shí)程放棄其。果線(xiàn)程然完成同代,則線(xiàn)出之前會(huì)放棄鎖。因此,只要調(diào)用notfy(*@authorleizhimin2008-9-20publicclassCalculatorextendsThreadintintpublicvoidrun()synchronized(this)for(inti=0;i<101;i++){total+=i;}}}}*@authorleizhimin2008-9-20publicclassReaderResultextendsThread{Calculatorc;publicReaderResult(Calculatorc)this.c=}publicvoidrun()synchronized(c)trySystem.out.println(Thread.currentThread()果。。。}catch(InterruptedExceptione)}System.out.println(Thread.currentThread計(jì)算結(jié)果為:}}publicstaticvoidmain(String[]args){Calculatorcalculator=newCalculator();newReaderResult(calculator).start();newnewnew}}Exceptioninthread"Thread-0"java.lang.IllegalMonitorStateException:currentthreadnotowneratjava.lang.Object.notifyAll(NativeMethod)atthreadtest.Calculatorrun(Calculator.java:18)Processfinishedwithexitcode實(shí)際上,上面這個(gè)代碼中,我們期望的是結(jié)果的線(xiàn)計(jì)算線(xiàn)程調(diào)用notifyAll()之前等待即可。但是,如果計(jì)算線(xiàn)程先執(zhí)行,并在結(jié)果線(xiàn)程等待之前調(diào)用了notify()方法,那么又會(huì) 因此,如果計(jì)算線(xiàn)程已經(jīng)調(diào)用了notifyAll()方法,那么它就不會(huì)再次調(diào)Java線(xiàn)程:線(xiàn)程的調(diào)度-休Java線(xiàn)程調(diào)度是Java多線(xiàn)程的,只有良好的調(diào)度,才能充分發(fā)揮系統(tǒng)的性能,提高程序的CPUCPU資源交給Thread.sleep(longmillis)Thread.sleep(longmillis,intnanos),均為靜態(tài)方sleepsleep,就休眠哪個(gè)線(xiàn)程。Java線(xiàn)程:線(xiàn)程的調(diào)度-*@authorleizhimin2009-11-4publicclassTestpublicstaticvoidmain(String[]args){Threadt1=newMyThread1();Threadt2=newThread(newMyRunnable());}}classMyThread1extendsThread{publicvoidrun(){for(inti=0;i<3;i++){System.out.println("1第i次執(zhí)行!");try}catch(InterruptedExceptione)}}}}classMyRunnableimplementsRunnable{publicvoidrun(){forfor(inti=0;i<3;i++)System.out.println("2第itry}catch(InterruptedExceptione)}}}}201011211222ProcessfinishedwithexitcodeJava線(xiàn)程:線(xiàn)程的調(diào)度-Java線(xiàn)程:線(xiàn)程的調(diào)度-*@authorleizhimin2009-11-4publicclassTestpublicstaticvoidmain(String[]args)ThreadThreadt1=newThreadt2=newThread(newMyRunnable());}}classMyThread1extendsThread{publicvoidrun(){for(inti=0;i<10;i++)System.out.println("1第i次執(zhí)行!");try{}catch(InterruptedExceptione)}}}}classMyRunnableimplementsRunnable{publicvoidrun(){for(inti=0;i<10;i++){System.out.println("2第i次執(zhí)行!");try}catch(InterruptedExceptione)}}}}10202111221213ProcessfinishedwithexitcodeJava線(xiàn)程:線(xiàn)程的調(diào)度-讓CPU資源,但是然給誰(shuí)不知道,僅僅是讓出,線(xiàn)程Java線(xiàn)程:線(xiàn)程的調(diào)度-*@authorleizhimin2009-11-4publicclassTestpublicstaticvoidmain(String[]args){Threadt1=newMyThread1();Threadt2=newThread(new}}classMyThread1extendsThread{publicvoidrun(){for(inti=0;i<10;i++)System.out.println("System.out.println("1第i}}}classMyRunnableimplementsRunnable{publicvoidrun(){for(inti=0;i<10;i++)System.out.println("2第i次執(zhí)行!");}}}2021222310111213141516171819242526272829ProcessfinishedwithexitcodeJava線(xiàn)程:線(xiàn)程的調(diào)度-合join方法。joinvoidvoidvoidjoin(longmillisvoidjoin(longmillis,intmillisnanosJava線(xiàn)程:線(xiàn)程的調(diào)度-*@authorleizhimin2009-11-4publicclassTestpublicstaticvoidmain(String[]args){Threadt1=newMyThread1();for(inti=0;i<20;i++)System.out.println("主線(xiàn)程第i次執(zhí)行!");if(i>2)try{//t1t1}catch(InterruptedExceptione)}}}}classMyThread1extendsThread{publicvoidrun(){for(inti=0;i<10;i++){System.out.println("1第i次執(zhí)行!");}}}012ProcessfinishedwithexitcodeJava線(xiàn)程:線(xiàn)程的調(diào)度-守護(hù)線(xiàn)守護(hù)線(xiàn)程使用的情況較少,但并非無(wú)用,舉例來(lái)說(shuō),JVM的回收、內(nèi)存管理等線(xiàn)程都是守publicfinalvoidpublicfinalvoidsetDaemon(booleanon)將該線(xiàn)程標(biāo)記為守護(hù)線(xiàn)程或用戶(hù)線(xiàn)程。當(dāng)正在運(yùn)行的線(xiàn)程都是守護(hù)線(xiàn)程時(shí),Java虛擬機(jī)退出。該方法首先調(diào)用該線(xiàn)程的checkAccess參數(shù)on如果為true,則將該線(xiàn)程標(biāo)記為守護(hù)線(xiàn)程。-SecurityException如果當(dāng)前線(xiàn)程無(wú)法修改該線(xiàn)程。isDaemon(),Java線(xiàn)程:線(xiàn)程的調(diào)度-*@authorleizhimin2009-11-4publicclassTestpublicstaticvoidmain(String[]args){Threadt1=new Threadt2newThread(newMyDaemon()); }} monextendsThread{publicvoidrun(){for(inti=0;i<5;i++){System.out.println("1第i次執(zhí)行!");try}catch(InterruptedExceptione)}}}}}classMyDaemonimplementsRunnable{publicvoidrun(){for(longi=0;i<9999999L;i++) 線(xiàn)程第itry}catch(InterruptedExceptione)}}}}010111212133144567Processfinishedwithexitcode實(shí)際上:JRE判斷程序是否執(zhí)行結(jié)束的標(biāo)準(zhǔn)是所有的前臺(tái)執(zhí)線(xiàn)程行完畢了,而不管線(xiàn)程的Java線(xiàn)程:線(xiàn)程的同步-同步方Java代碼中需要完成一下兩個(gè)操作:把競(jìng)爭(zhēng)的資源標(biāo)識(shí)為private;synchronized為了演示同步方法的使用,構(gòu)建了一個(gè)賬戶(hù),起初信用額為100w,然后模擬透支、存款Useroper(intJava*@authorleizhimin2009-11-4publicclassTestpublicstaticvoidmain(String[]args)Useru=new ",MyThreadt1=newMyThread("A",u,20);MyThreadt2newMyThread("B"u60);MyThreadt3newMyThread("C"u80);MyThreadt4newMyThread("Du,30);MyThreadt5=newMyThread("E",u,32);MyThreadt6=newMyThread("F",u,21);}}classMyThreadextendsThread{privateUseru;privateinty=MyThread(Stringname,Useru,inty)this.u=u;this.y=}publicvoidrun()}}classUserprivateStringcode;privateintUser(Stringcode,intcash)this.code=code;this.cash=cash;}publicStringgetCode()return}publicvoidsetCode(Stringcode)this.code=}@paramxxpublicsynchronizedvoidoper(intx)trytrythis.cash+=System.out.println(Thread.currentThread().getName運(yùn)行結(jié)束,增加“"+x+"”,當(dāng)前用戶(hù)賬戶(hù)余額為:"+cash);}catch(InterruptedExceptione)}}publicStringtoString()return"User{""code='"+code+'\''+",cash="+cash+}}線(xiàn)程線(xiàn)程A運(yùn)行結(jié)束,增加“20”,當(dāng)前用戶(hù)賬戶(hù)余額為:120線(xiàn)程F運(yùn)行結(jié)束,增加“21”,當(dāng)前用戶(hù)賬戶(hù)余額為:141線(xiàn)程E運(yùn)行結(jié)束,增加“32”,當(dāng)前用戶(hù)賬戶(hù)余額為:173C運(yùn)行結(jié)束,增加“-80”,當(dāng)前用戶(hù)賬戶(hù)余額為:93B運(yùn)行結(jié)束,增加“-60”,當(dāng)前用戶(hù)賬戶(hù)余額為:33線(xiàn)程D運(yùn)行結(jié)束,增加“-30”,當(dāng)前用戶(hù)賬戶(hù)余額為:3Processfinishedwithexitcode,不同步的情況,也就是去掉oper(intx)synchronized修飾符,然后運(yùn)行程序,線(xiàn)程線(xiàn)程A運(yùn)行結(jié)束,增加“20”,當(dāng)前用戶(hù)賬戶(hù)余額為:61線(xiàn)程D運(yùn)行結(jié)束,增加“-30”,當(dāng)前用戶(hù)賬戶(hù)余額為:63B運(yùn)行結(jié)束,增加“-60”,當(dāng)前用戶(hù)賬戶(hù)余額為:3線(xiàn)程F運(yùn)行結(jié)束,增加“21”,當(dāng)前用戶(hù)賬戶(hù)余額為:61線(xiàn)程E運(yùn)行結(jié)束,增加“32”,當(dāng)前用戶(hù)賬戶(hù)余額為:93C運(yùn)行結(jié)束,增加“-80”,當(dāng)前用戶(hù)賬戶(hù)余額為:61Processfinishedwithexitcode很顯然,上面的結(jié)果是錯(cuò)誤的,導(dǎo)致錯(cuò)誤的原因是多個(gè)線(xiàn)程并發(fā)了競(jìng)爭(zhēng)資源u,并對(duì)u的java.lang.Object類(lèi)。voidvoidvoidvoid導(dǎo)致當(dāng)前的線(xiàn)程等待,直到其他線(xiàn)程調(diào)用此對(duì)象的notify()notifyAll()voidwai
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 福州福州市于山風(fēng)景名勝公園管理處招聘講解員(兼文員)筆試歷年參考題庫(kù)附帶答案詳解
- 常州2025年常州市事業(yè)單位招聘筆試歷年參考題庫(kù)附帶答案詳解
- 河南工業(yè)職業(yè)技術(shù)學(xué)院《現(xiàn)代漢語(yǔ)單》2023-2024學(xué)年第二學(xué)期期末試卷
- 金肯職業(yè)技術(shù)學(xué)院《數(shù)據(jù)庫(kù)原理及應(yīng)用實(shí)訓(xùn)》2023-2024學(xué)年第二學(xué)期期末試卷
- 湖南城市學(xué)院《教育名著與經(jīng)典教育案例》2023-2024學(xué)年第二學(xué)期期末試卷
- 塔城職業(yè)技術(shù)學(xué)院《光電傳感器應(yīng)用技術(shù)》2023-2024學(xué)年第二學(xué)期期末試卷
- 江西水利職業(yè)學(xué)院《機(jī)器人機(jī)械系統(tǒng)》2023-2024學(xué)年第二學(xué)期期末試卷
- 上海電影藝術(shù)職業(yè)學(xué)院《所得稅》2023-2024學(xué)年第二學(xué)期期末試卷
- 科爾沁藝術(shù)職業(yè)學(xué)院《行政公文寫(xiě)作》2023-2024學(xué)年第二學(xué)期期末試卷
- 福建林業(yè)職業(yè)技術(shù)學(xué)院《工業(yè)生態(tài)學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 2024年北京大學(xué)強(qiáng)基計(jì)劃物理試題(附答案)
- 冷凍產(chǎn)品采購(gòu)合同范例
- 中職課件:職業(yè)道德與法治全冊(cè)教案
- 古詩(shī)詞誦讀《登岳陽(yáng)樓》公開(kāi)課一等獎(jiǎng)創(chuàng)新教學(xué)設(shè)計(jì)統(tǒng)編版高中語(yǔ)文必修下冊(cè)
- 醫(yī)務(wù)人員法律法規(guī)知識(shí)培訓(xùn)培訓(xùn)課件
- 鉚工理論考試題及答案
- JJF(魯) 116-2021 石油產(chǎn)品庫(kù)侖氯分析儀校準(zhǔn)規(guī)范
- 五人合伙開(kāi)酒吧協(xié)議書(shū)模板
- 2024年河北省中考化學(xué)真題(含解析)
- 中國(guó)越劇?唱腔智慧樹(shù)知到答案2024年浙江藝術(shù)職業(yè)學(xué)院
- 廣東省中山一中等七校聯(lián)合體2025屆高考臨考沖刺歷史試卷含解析
評(píng)論
0/150
提交評(píng)論