




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第10章多線程第10章多線程10.1多線程基本概念10.2創(chuàng)建線程的方式10.3線程的掛起與喚醒10.4多線程問題10.5小結(jié)210.1多線程基本概念文件輸入輸出裝置各種系統(tǒng)資源數(shù)據(jù)區(qū)段程序區(qū)段只有一個地方在執(zhí)行文件輸入輸出裝置各種系統(tǒng)資源數(shù)據(jù)區(qū)段程序區(qū)段同時有數(shù)個地方在執(zhí)行傳統(tǒng)的進(jìn)程多線程的任務(wù)310.1多線程基本概念多線程的優(yōu)勢:減輕編寫交互頻繁、涉及面多的程序的困難.程序的吞吐量會得到改善.(BT/多線程下載)在多個處理器的系統(tǒng),可以并發(fā)運行不同的線程.(否則,任何時刻只有一個線程在運行)410.1多線程基本概念線程與進(jìn)程的區(qū)別:進(jìn)程之間:內(nèi)部數(shù)據(jù)和狀態(tài)都完全獨立多線程:在同一進(jìn)程內(nèi)部,多線程共享一塊內(nèi)存空間和一組系統(tǒng)資源,有可能互相影響.線程本身的數(shù)據(jù)通常只有寄存器數(shù)據(jù),以及一個程序執(zhí)行時使用的堆棧,所以線程的切換比進(jìn)程切換的負(fù)擔(dān)要小。510.1多線程基本概念對線程的綜合支持是Java技術(shù)的一個重要特色.它提供了thread類、管程和條件變量的技術(shù).雖然Macintosh,WindowsNT,Windows9等操作系統(tǒng)支持多線程,但若要用C或C++編寫多線程程序是十分困難的,因為它們對數(shù)據(jù)同步的支持不充分.610.1多線程基本概念newThread()NewThreadRunnablestart()NotRunnablestop()stop()Deadyield()stop()orrun()exit..suspend()sleep()wait()notify()notifyAll(0resume().線程的狀態(tài)線程有四個狀態(tài):新生,運行,暫停,死亡710.2創(chuàng)建線程的方式1.繼承類ThreadpublicclassMythreadextendsThread 產(chǎn)生線程的對象ThreadnewThread=newMyThread();2.publicclassThreadByRunableimplementsRunnable(實現(xiàn)Runnable接口) 產(chǎn)生線程的對象ThreadnewThread=newThread(newThreadByRunable());4.啟動線程 newThread.start();810.2創(chuàng)建線程的方式5.run方法是運行線程的主體,啟動線程時,由java直接調(diào)用publicvoidrun()6.停止線程,由小應(yīng)用程序的stop調(diào)用線程的stopnewThread.stop()7sleep方法的作用,暫停線程的執(zhí)行,讓其它線程得到機會,sleep要拋出異常,必須捕捉.Try{sleep(100)}catch(InterruptedExceptione){}9例1:publicclassTestThreadextendsThread{publicTestThread(){}//空構(gòu)造方法publicvoidrun(){System.out.println("run()方法運行....");}publicstaticvoidmain(Stringarg[]){ TestThreadt=newTestThread();System.out.println("start()開始運行...");t.start();}}10.2創(chuàng)建線程的方式1010.2創(chuàng)建線程的方式例2:帶休息的線程publicclasstestThreadextendsThread{publictestThread(){}publicvoidrun(){for(inti=0;i<100;i++){System.out.println(i+":run()方法運行....");
try{sleep(1000);//休息一秒鐘}catch(InterruptedExceptione){}}}publicstaticvoidmain(Stringarg[]){testThreadt=newtestThread();System.out.println("start()開始運行...");t.start();}}11例3,多個線程猜猜程序執(zhí)行結(jié)果publicclassMultiThreadextendsThread{intthreadNo;//給線程一個編號標(biāo)志publicMultiThread(intno){threadNo=no;}publicvoidrun(){for(inti=0;i<1000;i++){System.out.println("Thread:"+threadNo+""+i+":run()方法運行....");}}//endofrunpublicstaticvoidmain(Stringarg[]){MultiThreadmt1=newMultiThread(1);MultiThreadmt2=newMultiThread(2);System.out.println("start()開始運行...");mt1.start();mt2.start();}}1210.2創(chuàng)建線程的方式8.其它常用的方法isAlive:判斷線程目前是否正在執(zhí)行狀態(tài)中if(newthread.isAlive())newthread.stop();resume:要求被暫停得線程繼續(xù)執(zhí)行suspend:暫停線程的執(zhí)行interrupt:中斷正在運行中的線程join:等待線程執(zhí)行完畢thatThread.join();被等待的那個線程不結(jié)束,當(dāng)前線程就一直等待.yield():避讓,將執(zhí)行的權(quán)力交給其它線程,自己到隊列的最后等待.1310.2創(chuàng)建線程的方式9.線程的優(yōu)先權(quán)某一時刻只有一個線程在執(zhí)行,調(diào)度策略為固定優(yōu)先級調(diào)度.線程可以給定自1-10的10個不同優(yōu)點級,1最低,10最高設(shè)置方法:newthread.setPriority(Thread.MIN_PRIORITY)級別有:MIN-PRIORITYNOM_PRIORITYMAX-PRIORITY10.自私的線程:有很高的優(yōu)先權(quán)的線程,不主動睡眠或讓出處理器控制權(quán).14例4,設(shè)定優(yōu)先級后的多線程publicclassPrioritiedThreadextendsThread{intthreadNo;
publicPrioritiedThread(intno){threadNo=no;}publicvoidrun(){for(inti=0;i<1000;i++){System.out.println("Thread:"+threadNo+""+i+":run()方法");}}publicstaticvoidmain(Stringarg[]){PrioritiedThreadmt1=newPrioritiedThread(1);PrioritiedThreadmt2=newPrioritiedThread(2);System.out.println("start()開始運行...");mt1.setPriority(3);mt2.setPriority(8);mt1.start();mt2.start();}}15多線程同時運行的特點:多個進(jìn)程運行時執(zhí)行順序是交叉的多個線程運行時,調(diào)度策略為固定優(yōu)先級調(diào)度.級別相同時,由操作系統(tǒng)按時間片來分配較高的優(yōu)先權(quán)的線程運行時間多,較低獲得較少運行時間1610.3線程的結(jié)束方式當(dāng)一個線程執(zhí)行完所有語句后就自動終止,調(diào)用線程的stop()方法,也可以強制終止線程。如果希望線程正常終止,可采用標(biāo)記來使線程中的run()方法退出。1710.3線程的結(jié)束方式publicclassXyzimplementsRunnable{privatebooleantimeToQuit=false;publicvoidrun(){while(!timeToQuit){…..}//cleanupbeforerun()ends;}publicvoidstopRunning(){timeToQuit=true;}}1810.3線程的結(jié)束方式publicclassControlThread{privateRunnabler=newXyz();privateThreadt=newThread(r);
publicvoidstartThread(){t.start();}
publivoidstopThread(){r.stopRunning();}}1910.4多線程問題---如何寫多線程1.分別定義不同的線程類,在各自的run方法中定義線程的工作
classmythread1extendsThread{publicvoidrun{….}}classmythread2extendsThread{publicvoidrun{….}}2.在主類中實例化各線程類,并啟動線程.publicclassdemoextendsApplet{publicvoidinit(){mythreadt1=newmythread1();mythreadt2=newmythread2();t1.start();t2.start();}}2010.4多線程問題---如何寫多線程練習(xí):將窗口分為上下兩個區(qū),分別運行兩個線程,一個在上面的區(qū)域中顯示由右向左游動的字符串,另一個在下面的區(qū)域從左向右游動的字符串.方法一:一個線程,在paint方法中使用兩個輸出字符串的語句publicvoidpaint(Graphicsg){ify1<0y1=200elsey1=y1-10;ify2>200y2=0elsey2=y2+10;g.drawString(“hello,Java!”,20,y1,);g.drawString(“hello,Java!”,40,y2,);}2110.4多線程問題---如何寫多線程方法二:定義兩個類,運行各自的線程,各自有自己的paint()方法.注意:兩個小應(yīng)用程序必須是panel類或者是canvas類,將小應(yīng)用的區(qū)域分成兩塊,否則不能運行paint語句.2210.4多線程問題---線程間的通信1.線程間的通信可以用管道流,.創(chuàng)建管道流:PipedInputStreampis=newPipedInputStream();PipedOutputStreampos=newPipedOutputStream(pis);或:PipedOutputStreampos=newPipedOutputStream();PipedInputStreampis=newPipedInputStream(pos);線程1PipedOutputStreamPipedInputStream輸出流outStream輸入流inStream線程22310.4多線程問題---線程間的通信管道流不能直接讀寫PrintStreamp=newPrintStream(pos);p.println(“hello”);DataInputStreamd=newDataInputStream(pis);d.readLine();2.通過一個中間類來傳遞信息.線程2線程1中間類mssm.write(s)s=m.read()write()read()printStreamDataInputStream2410.4多線程問題--線程間的通信管道流可以連接兩個線程間的通信下面的例子里有兩個線程在運行,一個往外輸出信息,一個讀入信息.將一個寫線程的輸出通過管道流定義為讀線程的輸入.outStream=newPipedOutputStream();inStream=newPipedInputStream(outStream);newWriter(outStream).start();newReader(inStream).start();
2510.4多線程問題--線程間的通信主類Pipethread輔類Writer線程類輔類Reader線程類管道流將數(shù)據(jù)寫到輸出流從流中讀數(shù)據(jù)輸入流作為參數(shù)傳給WriterWriter(outStream)2610.4多線程問題--線程間的通信.publicclassPipethread{
publicstaticvoidmain(Stringargs[]){PipethreadthisPipe=newPipethread();thisPcess();}publicvoidprocess(){PipedInputStreaminStream;PipedOutputStreamoutStream;PrintStreamprintOut;try{outStream=newPipedOutputStream(); inStream=newPipedInputStream(outStream);
newWriter(outStream).start();
newReader(inStream).start();
}catch(IOExceptione){}}}2710.4多線程問題---讀管道線程classReaderextendsThread{privatePipedInputStreaminStream;//從中讀數(shù)據(jù)
publicReader(PipedInputStreami){inStream=i;}publicvoidrun(){Stringline;DataInputStreamd;booleanreading=true;try{d=newDataInputStream(inStream); while(reading&&d!=null){ try{line=d.readLine(); if(line!=null){ System.out.println(”讀:"+line);} elsereading=false; }catch(IOExceptione){}}catch(Exceptione){System.exit(0);} try{Thread.sleep(4000);} catch(InterruptedExceptione){}}}2810.4多線程問題—寫數(shù)據(jù)線程.classWriterextendsThread{privatePipedOutputStreamoutStream;//將數(shù)據(jù)輸出privateStringmessages[]={"Monday","Tuesday","Wednsday", "Thursday","Friday:","Saturday:","Sunday:"};publicWriter(PipedOutputStreamo)
{outStream=o;}publicvoidrun()
{PrintStreamp=newPrintStream(outStream);for(inti=0;i<messages.length;i++){
p.println(messages[i]);//向管道中寫出數(shù)據(jù) p.flush(); System.out.println(“寫:"+messages[i]);} p.close();p=null;}}2910.5多線程問題---資源協(xié)調(diào)1.數(shù)據(jù)的完整性線程1線程2線程10資源取過來加1后送回去withdrwal()withdrwal()透支余額變量3010.5多線程問題---資源協(xié)調(diào)互斥鎖(管程):對共享對象的訪問必須同步,Java通過管程實現(xiàn)線程的同步.(英文名為Monitor有的參考書稱其為監(jiān)視器)互斥鎖是一個對象,包含共享的數(shù)據(jù),也包含阻止兩個線程同時訪問同一個數(shù)據(jù)的機制,象鎖一樣作用在數(shù)據(jù)上.Java為每個擁有synchronized方法的實例對象提供一個唯一的互斥鎖(管程),互斥鎖入口就是synchronized方法的入口,調(diào)用該方法就接受它的管理。圖示:withdrawal1為一實現(xiàn)了管程的方法線程1進(jìn)入withdrawal方法時,獲得(加鎖);當(dāng)線程1的方法執(zhí)行完畢返回時,開鎖,線程2的withdrawal方能進(jìn)入.withdrawal()線程1互斥鎖線程23110.4多線程問題---資源協(xié)調(diào)用synchronized來標(biāo)識的區(qū)域或方法即為管程監(jiān)視的部分。一個類或一個對象有一個管程,如果一個程序內(nèi)有兩個方法使用synchronized標(biāo)志,則他們在一個管程管理之下.一般情況下,只在方法的層次上使用關(guān)鍵區(qū)getput監(jiān)視器線程1線程23210.4多線程問題---資源協(xié)調(diào)此處給出的例子演示兩個線程在同步限制下工作的情況.classAccount{staticsintbalance=1000;//為什么用static?staticsintexpense=0;publicsynchronizedvoidwithdrawl(intamount){if(amount<=balance){balance-=amount;expense+=amount;}else{System.out.println(“bounced:“+amount);}}}3310.4多線程問題---資源協(xié)調(diào)2.等待同步數(shù)據(jù)生產(chǎn)者消費者..共享對象put()get()可能出現(xiàn)的問題:生產(chǎn)者比消費者快時,消費者會漏掉一些數(shù)據(jù)沒有取到消費者比生產(chǎn)者快時,消費者取相同的數(shù)據(jù).notify()和wait()方法用來協(xié)調(diào)讀取的關(guān)系.notify()和wait()都只能從同步方法中的調(diào)用.3410.4多線程問題---資源協(xié)調(diào)notify()的作用是喚醒正在等待同一個管程的線程.wait()的作用是讓當(dāng)前線程等待信息版例子get()方法在讀信息之前先等待,直到信息可讀,讀完后通知要寫的線程.put()方法在寫信息之前先等待,直到信息被取走,寫完后通知要讀的進(jìn)程.3510.4多線程問題---資源協(xié)調(diào)ProducerConsumeraaaaPCQueue3610.4多線程問題---資源協(xié)調(diào)publicclassProducerConsumerDemo1{publicstaticvoidmain(String[]args){PCQueuec=newPCQueue();Producerp1=newProducer(c,1);Consumerc1=newConsumer(c,1);p1.start();c1.start();}}3710.3多線程問題---資源協(xié)調(diào)//定義一個隊列classPCQueue{//一個實現(xiàn)管程的類privateintseq;privatebooleanavailable=false;//定義一個可用性標(biāo)志publicsynchronizedintget(){while(available==false){try{wait();}catch(InterruptedExceptione){}}available=false;notifyAll();returnseq;}publicsynchronizedvoidput(intvalue){while(available==true){try{wait();}catch(InterruptedExceptione){}}available=true;seq=value;notifyAll();}}3810.3多線程問題
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廢氣廢氣在線運維規(guī)定合同
- 智慧酒店運營投資合同
- 住宅樓房地產(chǎn)買賣合同
- 活動場地租用合同
- 服務(wù)合同尾款協(xié)議
- 汽車臨時出租合同協(xié)議書
- 合同不執(zhí)行協(xié)議書怎么寫
- 銷售辦公桌合同協(xié)議
- 租電合同協(xié)議
- 人工協(xié)議合同
- 中考語文復(fù)習(xí)指導(dǎo)PPT資料30頁課件
- FZ∕T 63006-2019 松緊帶
- 交叉口的vissim仿真與優(yōu)化畢業(yè)論文
- 案例收球器盲板傷人事故
- 第3章-中子擴散理論2014
- 銀行存款余額調(diào)節(jié)表正式版
- 2×100+2×200MW供熱式火力發(fā)電廠
- 模具驗收檢查表(出口模具)
- bim畢業(yè)設(shè)計--精選文檔
- 某紡織廠供配電系統(tǒng)設(shè)計(DOC25頁)
- biomedical Signal processing 生物醫(yī)學(xué)信號處理 Chapter
評論
0/150
提交評論