java線程.大數(shù)據(jù)學(xué)院本教程研究了基礎(chǔ)知識是、為什么有用以及怎么開_第1頁
java線程.大數(shù)據(jù)學(xué)院本教程研究了基礎(chǔ)知識是、為什么有用以及怎么開_第2頁
java線程.大數(shù)據(jù)學(xué)院本教程研究了基礎(chǔ)知識是、為什么有用以及怎么開_第3頁
java線程.大數(shù)據(jù)學(xué)院本教程研究了基礎(chǔ)知識是、為什么有用以及怎么開_第4頁
java線程.大數(shù)據(jù)學(xué)院本教程研究了基礎(chǔ)知識是、為什么有用以及怎么開_第5頁
免費預(yù)覽已結(jié)束,剩余54頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

有什么內(nèi)容

第一章我應(yīng)該學(xué)習(xí)這個嗎關(guān)于BrianGoetzdeveloperWorksJava15直是專業(yè)軟件開發(fā)人員。他是Quiotix的首席顧問,這是一家位于加利福尼亞州阿爾托斯在流行的業(yè)界物上可以看到Brian和即將的文章。 聯(lián)系Brian。第二章線程基什么是線幾乎每種操作系統(tǒng)都支持進程的概念——進程就是在某種程度上相互的、獨立運行的程序線程之間的程度要小。它們共享內(nèi)存、文件句柄和其它每個進程應(yīng)有的狀態(tài)。每個Java程序都使用線JavaJava,JVM在該線程中調(diào)用程序的main()方法。任務(wù)相關(guān)的線程。其它工具也創(chuàng)建線程,如AWT(抽象窗口工具箱( SwingUI工具箱、servlet容器、應(yīng)用程序服務(wù)器和RMI(方法調(diào)用(RemoteMethod為什么使用線UI響應(yīng)更快的AWT和Swing程序把事件偵與UI對象連接。當特定事件(如單擊了某個按鈕)發(fā)生時,這些偵會得到通知。事件偵是在AWT事件線程中調(diào)用的。如果事件偵要執(zhí)行持續(xù)很久的任務(wù),如檢查一個大文檔中的拼寫,事件線忙于運行拼寫檢查器,所以在完成事件偵之前,就不能處理額外的UI事件。這就會使程序看來似乎停滯了,執(zhí)行過程中就可以繼續(xù)處理UI事件(包括取消正在執(zhí)行的長時間運行任務(wù)的請求)。利用多處理器 服務(wù)器系統(tǒng)—甚至是一些臺式機系統(tǒng)—都有多個處理器。Linux、SolarisWindowsNT/2000,都可以利用多個處理器并調(diào)度線程在簡化在某些情況下,使用線程可以使程序編寫和起來更簡單。考慮一個仿真應(yīng)用程序,您要在其中異步或處SocketInputStream.read()的調(diào)用將會阻塞,直到有可用數(shù)據(jù)為止。如果單線程程序要套接字,而套接字另一端的實體并未發(fā)送任何數(shù)據(jù),那么該程序只會等簡單,但有時不要示例:使用一個線程用于計時,并使用另一個線程完成工作查的標志。十秒鐘之后,主線停止。請注意,共享標志被成volatile。*CalculatePrimes--calculateasmanyprimesaswecanintenpublicclassCalculatePrimesextendsThreadpublicstaticfinalintMAX_PRIMES= publicstaticfinalintTEN_SECONDS=10000;publicvolatilebooleanfinished=publicvoidrun()int[]primes=newint[MAX_PRIMES];intcount=0;for(inti=2;count<MAX_PRIMES;i++)//Checktoseeifthetimerhasexpiredif(finished){}booleanprime=for(intj=0;j<count;{if(i%primes[j]==0){prime=false;}}if{primes[count++]=i;System.out.println("Foundprime:"+i);}}}publicstaticvoidmain(String[]{CalculatePrimescalculator=newtry{}catch(InterruptedExceptione)//fall}calculator.finished=}}小GUI論這些規(guī)則。所有這些規(guī)則歸結(jié)為一條基本原則:了同步。第三章創(chuàng)建通過Thread構(gòu)造器或?qū)嵗^承類Thread的類來創(chuàng)建的。Java線程可以通過直接實例化Thread對象或?qū)嵗^承Thread的對象來創(chuàng)建其它線程。程類型的對象(它繼承了Thread),創(chuàng)建了一個線程。當我們討論Java程序中的線程時,也許會提到兩個相關(guān)實體:完成工作的實際線程或代表線程的ThreadThreadJavaVM控制相關(guān)線程的式。創(chuàng)建線程和啟動線程并Threadstart通常在構(gòu)造器中通過start()啟動線程并不是好主意。這樣做,會把部分構(gòu)造的對象給新的線start()init結(jié)束run()ExceptionError加入ThreadAPIjoinThread.joinThread.join()調(diào)除了何時使用Thread.join()Object.wait序變量。如果線程要其它線程可以看見的變量,如從靜態(tài)字段(全局變量)直接或間接的publicclassTwoThreadspublicstaticclassThread1extends{publicvoidrun(){}}publicstaticclassThread2extends{publicvoidrun(){}}publicstaticvoidmain(String[]{newThread1().start();newThread2().start();}}12A1A21ABA12A1BAB1休ThreadAPI包含了一個sleep()方法,它將使當前線程進入等待狀態(tài),直到過了一段指定時間,ThreadTerrupt(),從而中斷了線程。當Thread.yield()守護程序我們提到過當Java程序的所有線程都完成時,該程序就退出,但這并不完全正確。隱藏的系統(tǒng)線程,如收集線程和由JVM創(chuàng)建的其它線程會怎么樣?我們沒有辦法停止這些線程。如果那些線程正在運行,那么Java程序怎么退出呢?Thread.setDaemon()護程序線程。您也許想要使用守護程序線程作為在程序中創(chuàng)建的線程,如計時器線程或其它延示例:用多個線程分解Createstenthreadstosearchfor umvalueofalargeEachthreadsearchesoneportionofthepublicclassTenThreadsprivatestaticclassWorkerThreadextends{intmax=Integer.MIN_VALUE;int[]ourArray;publicWorkerThread(int[]{this.ourArray=}//Findthe umvalueinourparticularpieceofthearraypublicvoidrun(){for(inti=0;i<ourArray.length;i++)max=Math.max(max,ourArray[i]);}publicint{return}}publicstaticvoidmain(String[]{WorkerThread[]threads=newWorkerThread[10];int[][]bigMatrix=getBigHairyMatrix();intmax=//Giveeachthreadasliceofthematrixtoworkwithfor(inti=0;i<10;i++){threads[i]=newWorkerThread(bigMatrix[i]);}//Waitforeachthreadtofinishtry{for(inti=0;i<10;{max=Math.max(max,}}catch(InterruptedExceptione)//fall} umvaluewas"+}}小ThreadThreadThreadstartrun()第四章無處不在的誰創(chuàng)建線AWTAWTSwingAWTUI任何由AWT事件調(diào)用的事件偵都在AWT事件線程中執(zhí)行。讓由事件偵觸發(fā)的長時間運行任務(wù)(如在大文檔中檢查拼寫或在文件系統(tǒng)中搜索一個文件)在線程中運行,這樣當該任務(wù)運行時,UI就不會停滯了(這可能還會用戶取消操作)。這樣做的一個好的框架示例是SwingWorker類(請參閱參考資料)。JDK1.3中,TimerTask工具被引入到Java語言。這個便利的工具可以稍后在某個時間執(zhí)行publicstaticvoidmain(String[]{Timertimer=newfinalCalculatePrimescalculator=newCalculatePrimes();new{publicvoid{calculator.finished=}},}servletJavaServerPages一個servlet可能會同時在多個線程中是活動的。servletJavaServerPages(JSP)同一個servlet或JSP文件。必須適當同步servlet或JSP文件的任何共享數(shù)據(jù);這包括servlet對象本身的字段。實現(xiàn)RMIRMI工具可以調(diào)用對在其它JVM中運行的對象進行的操作。當調(diào)用方法時,RMI編譯器創(chuàng)建的RMI存根會打包方法參數(shù),并通過網(wǎng)絡(luò)將它們發(fā)送到系統(tǒng),然后系統(tǒng)會將它們解包并假設(shè)您創(chuàng)建了一個RMI對象,并將它到RMI表或者Java命名和接口(JavaNamingandDirectoryInterface(JNDI))名稱空間。當客戶機調(diào)用其中的一個方法時,該方在RMIUnicastRemoteObjectUnicastRemoteObject始化用于分派方法調(diào)用的基礎(chǔ)結(jié)構(gòu)。這包括用于接收調(diào)用請求的套接字偵,和一個或多個執(zhí)行請求的線程。小線程通過幾種機制進入JavaThreadAWTjava.util.TimerTaskservletJSP第五章共享對數(shù)據(jù)共享存在于同一個內(nèi)存空間中的所有進程上下文,包括內(nèi)存。這非常便利,但也有重大責任。只要共享變量(靜態(tài)或?qū)嵗侄危€程就可以方便地互相交換數(shù)據(jù),但線程還必須確保它們以受控的方式共享變量,以免它們互受控的同volatileSynchronized有兩個重要含義:它確保了一次只有一個線程可以執(zhí)行代碼的受保護部分(互斥,確保共享數(shù)據(jù)更改的可處理器可以使用高速緩存加速對內(nèi)存的(或者編譯器可以將值到寄存器中以便進行更快的的值!這聽起來很嚇人,但它卻很常見。它只是表示在其它線程使用或修改的數(shù)據(jù)時,必須遵Volatile比同步更簡單,只適合于控制對基本變量(整數(shù)、布爾變量等)的單個實例的。當一個變量被成volatile,任何對該變量的寫操作都會繞過高速緩存,直接寫入主內(nèi)存,而任何對用鎖保護的原子代每個Java對象都有一個相關(guān)的鎖。同一時間只能有一個線程持有Java鎖。當線程進入簡單的同步示(或“00”,隨便您信不信)publicclassSyncExampleprivatestaticlockObject=newObject();privatestaticclassThread1extendsThread{publicvoid{synchronized(lockObject){x=y=0;}}}privatestaticclassThread2extends{publicvoidrun(){synchronized(lockObject){x=y=1;}}}publicstaticvoidmain(String[]{newnew}}Java須記住是鎖的保護了代碼塊,而不是代碼塊本身,這一點很重要。一個鎖可以保護許多代碼塊setLastAccesssynchronized每個線程有一個不同的thingie值。因此,synchronized代碼塊受到兩個正在執(zhí)行的線程中不同publicclass{publicstaticclass{privateDatepublicsynchronizedvoidsetLastAccess(Date{this.lastAccess=}}publicstaticclassMyThreadextends{privateThingiepublicMyThread(Thingie{this.thingie=}publicvoid{thingie.setLastAccess(new}}publicstaticvoid{Thingiethingie1=newthingie2=newnewMyThread(thingie1).start();new}}同步publicclassPointpublicsynchronizedvoidsetXY(intx,int{this.x=x;this.y=y;}}僅僅因為setXY()被成synchronized并不表示兩個不同的線程不能同時執(zhí)行setXY(),只要PointsetXY()Point程執(zhí)行setXY(),或Point的任何其它synchronized方法。同步的塊。Point的以下版本等價于前一頁中顯示的版本:publicclassPointpublicvoidsetXY(intx,int{synchronized(this){this.x=x;this.y=}}}大多數(shù)類并沒用同步。這表示在沒有附加同步的情況下,不能在多個線程中使用諸如HashMap這樣的類。通過每次共享集合中的方法時使用同步,可以在多線程應(yīng)用程序中使用Collection類。對于CollectionsList、MapSetCollections.synchronizedMap封裝Map,它將確保所有對該映射的都被正確同步。示例:簡單的線程安全的高synchronizedgetObject和clearCache方法,而沒有數(shù)據(jù)損壞的風(fēng)險。publicclassSimpleCacheprivatefinalMapcache=newpublicObjectload(StringobjectName)//loadtheobject}publicvoid{synchronized(cache){}}publicObjectgetObject(String{synchronized(cache)Objecto=if(o==null)o=load(objectName);cache.put(objectName,o);}}return}}小synchronized第六章同步詳細互如什么時候必須用于一致性的publicclass{publicinttop=publicint[]values=newpublicvoidpush(int{values[top++]=}publicint{returnvalues[--}}如果多個線程試圖同時使用這個類,會發(fā)生什么?這可能是個。因為沒有同步,多個線程可以同時執(zhí)行push()和pop()。如果一個線程調(diào)用push(),而另一個線程正好在遞增了top并要把它用作values的下標之間調(diào)用push(),會發(fā)生什么?結(jié)果,這兩個線程會把它們的新值到相volatilesynchronizedtopvalues遞增共享計數(shù)publicclass{privateintcounter=publicintget() {returncounter;}publicvoidset(intn){counter=n;}publicvoidincrement(){set(get()+}}increment()如果兩個線程試圖同時執(zhí)行increment(),會發(fā)生什么?計數(shù)器也許會增加1,也許增加2。令人countervolatileget()set()synchronized那么這兩個線程都看不到對方的更新,即使counter是volatile,或者get()和set()是要使遞增操作正確運行,不僅get()和set()必須是synchronized,而且increment()也必需synchronizedincrement()increment()Vector不變性和finalJavaString、IntegerBigDecimal,都是不可改變的:一旦構(gòu)造之后,它們的當程之間共享final字段時,不需要擔心同步。什么時候不需final字段時死只要您擁有多個進程,而且它們要爭用對多個鎖的獨占,那么就有可能發(fā)生死鎖。如果有一組最常見的死鎖形式是當線程1AB2象B上的鎖,卻正在等待對象A上的鎖。這兩個線程都不會獲得第二個鎖,或者釋放第一個性能考慮在編寫并發(fā)代碼時,除非看到性能問題的確鑿,否則不要過多能。瓶頸往往出現(xiàn)在我們性為代價—是一樁賠本的生意。同步盡量簡短。把不隨線程變化的預(yù)處理和后處理移出synchronized塊。第七章其它線程API詳細wait()、notify()notifyAll()Wait()Terrupt()程用notify()或notifyAll()喚醒它。中一個線程。當對某個對象調(diào)用notifyAll()時,會喚醒所有正在等待該對象的線程。這些方法是更復(fù)雜的鎖定、排隊和并發(fā)性代碼的構(gòu)件。但是,notify()和notifyAll()的使用很notify()notifyAll則就使用notifyAll()。與其使用wait()和notify()來編寫您自己的調(diào)度程序、線程池、隊列和鎖,倒不如使用util.concurrent(請參閱參考資料),這是一個被廣泛使用的開放源碼工具箱,里面都是有用的并發(fā)性實用程序。JDK1.5將包括java.util.concurrent包;它的許多類都派生自線程統(tǒng)調(diào)度程序取決于實現(xiàn)。在某些實現(xiàn)中,多個—甚至全部—優(yōu)先級可能被映射成相同的底層操您最好只使用Thread中的等價方法。ThreadGroup.uncaughtException()方法。這就有機會關(guān)閉系統(tǒng)、將一條消息寫到日志文件或SwingUtilitiesThreadAPI正如前面提到的,Swing應(yīng)用程序有一個UI線程(有時叫稱為事件線程),所有UI活動都必須SwingUtilities.invokeLater()方法可以將Runnable對象傳送給它,并且在事件線程中執(zhí)行會阻塞,直到Runnable完成執(zhí)行之后。voidshowoThereDialog()throws{RunnableshowModalDialog=newRunnable()publicvoidrun(){JOptionPane.showMessageDialog(myMainFrame, oThere");}}AWTjava.awt.EventQueueinvokeLater()invokeAndWait(第八章結(jié)束語和參考資JavaServlet、RMI、JavaServerPages或EnterpriseJavaBeans技術(shù),您可能沒有您正能由另一個線程寫過的變量時,必須使用同步以確保對數(shù)據(jù)的更改程之間是可見的。當使用同步保護共享變量時,必須確保不僅使用了同步,而且器和寫入器在同一個器上同法并不能使它變成線程安全的—只會使它更容易發(fā)生死鎖。參考DougLeautil.concurrent(文章“SynchronizationandtheJa

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論