版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第10章多線程第10章多線程10.1多線程基本概念10.2創(chuàng)建線程的方式10.3線程的掛起與喚醒10.4多線程問題10.5小結210.1多線程基本概念文件輸入輸出裝置各種系統(tǒng)資源數(shù)據(jù)區(qū)段程序區(qū)段只有一個地方在執(zhí)行文件輸入輸出裝置各種系統(tǒng)資源數(shù)據(jù)區(qū)段程序區(qū)段同時有數(shù)個地方在執(zhí)行傳統(tǒng)的進程多線程的任務310.1多線程基本概念多線程的優(yōu)勢:減輕編寫交互頻繁、涉及面多的程序的困難.程序的吞吐量會得到改善.(BT/多線程下載)在多個處理器的系統(tǒng),可以并發(fā)運行不同的線程.(否則,任何時刻只有一個線程在運行)410.1多線程基本概念線程與進程的區(qū)別:進程之間:內部數(shù)據(jù)和狀態(tài)都完全獨立多線程:在同一進程內部,多線程共享一塊內存空間和一組系統(tǒng)資源,有可能互相影響.線程本身的數(shù)據(jù)通常只有寄存器數(shù)據(jù),以及一個程序執(zhí)行時使用的堆棧,所以線程的切換比進程切換的負擔要小。510.1多線程基本概念對線程的綜合支持是Java技術的一個重要特色.它提供了thread類、管程和條件變量的技術.雖然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直接調用publicvoidrun()6.停止線程,由小應用程序的stop調用線程的stopnewThread.stop()7sleep方法的作用,暫停線程的執(zhí)行,讓其它線程得到機會,sleep要拋出異常,必須捕捉.Try{sleep(100)}catch(InterruptedExceptione){}9例1:publicclassTestThreadextendsThread{publicTestThread(){}//空構造方法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í)行結果publicclassMultiThreadextendsThread{intthreadNo;//給線程一個編號標志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();被等待的那個線程不結束,當前線程就一直等待.yield():避讓,將執(zhí)行的權力交給其它線程,自己到隊列的最后等待.1310.2創(chuàng)建線程的方式9.線程的優(yōu)先權某一時刻只有一個線程在執(zhí)行,調度策略為固定優(yōu)先級調度.線程可以給定自1-10的10個不同優(yōu)點級,1最低,10最高設置方法:newthread.setPriority(Thread.MIN_PRIORITY)級別有:MIN-PRIORITYNOM_PRIORITYMAX-PRIORITY10.自私的線程:有很高的優(yōu)先權的線程,不主動睡眠或讓出處理器控制權.14例4,設定優(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多線程同時運行的特點:多個進程運行時執(zhí)行順序是交叉的多個線程運行時,調度策略為固定優(yōu)先級調度.級別相同時,由操作系統(tǒng)按時間片來分配較高的優(yōu)先權的線程運行時間多,較低獲得較少運行時間1610.3線程的結束方式當一個線程執(zhí)行完所有語句后就自動終止,調用線程的stop()方法,也可以強制終止線程。如果希望線程正常終止,可采用標記來使線程中的run()方法退出。1710.3線程的結束方式publicclassXyzimplementsRunnable{privatebooleantimeToQuit=false;publicvoidrun(){while(!timeToQuit){…..}//cleanupbeforerun()ends;}publicvoidstopRunning(){timeToQuit=true;}}1810.3線程的結束方式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多線程問題---如何寫多線程練習:將窗口分為上下兩個區(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()方法.注意:兩個小應用程序必須是panel類或者是canvas類,將小應用的區(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é)調1.數(shù)據(jù)的完整性線程1線程2線程10資源取過來加1后送回去withdrwal()withdrwal()透支余額變量3010.5多線程問題---資源協(xié)調互斥鎖(管程):對共享對象的訪問必須同步,Java通過管程實現(xiàn)線程的同步.(英文名為Monitor有的參考書稱其為監(jiān)視器)互斥鎖是一個對象,包含共享的數(shù)據(jù),也包含阻止兩個線程同時訪問同一個數(shù)據(jù)的機制,象鎖一樣作用在數(shù)據(jù)上.Java為每個擁有synchronized方法的實例對象提供一個唯一的互斥鎖(管程),互斥鎖入口就是synchronized方法的入口,調用該方法就接受它的管理。圖示:withdrawal1為一實現(xiàn)了管程的方法線程1進入withdrawal方法時,獲得(加鎖);當線程1的方法執(zhí)行完畢返回時,開鎖,線程2的withdrawal方能進入.withdrawal()線程1互斥鎖線程23110.4多線程問題---資源協(xié)調用synchronized來標識的區(qū)域或方法即為管程監(jiān)視的部分。一個類或一個對象有一個管程,如果一個程序內有兩個方法使用synchronized標志,則他們在一個管程管理之下.一般情況下,只在方法的層次上使用關鍵區(qū)getput監(jiān)視器線程1線程23210.4多線程問題---資源協(xié)調此處給出的例子演示兩個線程在同步限制下工作的情況.classAccount{staticsintbalance=1000;//為什么用static?staticsintexpense=0;publicsynchronizedvoidwithdrawl(intamount){if(amount<=balance){balance-=amount;expense+=amount;}else{System.out.println(“bounced:“+amount);}}}3310.4多線程問題---資源協(xié)調2.等待同步數(shù)據(jù)生產(chǎn)者消費者..共享對象put()get()可能出現(xiàn)的問題:生產(chǎn)者比消費者快時,消費者會漏掉一些數(shù)據(jù)沒有取到消費者比生產(chǎn)者快時,消費者取相同的數(shù)據(jù).notify()和wait()方法用來協(xié)調讀取的關系.notify()和wait()都只能從同步方法中的調用.3410.4多線程問題---資源協(xié)調notify()的作用是喚醒正在等待同一個管程的線程.wait()的作用是讓當前線程等待信息版例子get()方法在讀信息之前先等待,直到信息可讀,讀完后通知要寫的線程.put()方法在寫信息之前先等待,直到信息被取走,寫完后通知要讀的進程.3510.4多線程問題---資源協(xié)調ProducerConsumeraaaaPCQueue3610.4多線程問題---資源協(xié)調publicclassProducerConsumerDemo1{publicstaticvoidmain(String[]args){PCQueuec=newPCQueue();Producerp1=newProducer(c,1);Consumerc1=newConsumer(c,1);p1.start();c1.start();}}3710.3多線程問題---資源協(xié)調//定義一個隊列classPCQueue{//一個實現(xiàn)管程的類privateintseq;privatebooleanavailable=false;//定義一個可用性標志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)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 安全監(jiān)控系統(tǒng)值機人員、維護人員職責
- 2024年陜西客運員證是考什么內容
- 2024年福州客運從業(yè)資格證考試試題庫及答案解析
- 2024年浙江客運資格證考幾個科目
- 2024年鶴崗申請客運從業(yè)資格證版試題
- 2024年江蘇客運資格證急救止血法
- 2024年葫蘆島客運從業(yè)資格證理論考試答案
- 2024年山西客運從業(yè)資格證試題下載
- 物理-浙江省湖州、衢州、麗水2024年11月三地市高三教學質量檢測試卷試題和答案
- 吉首大學《環(huán)境保護法學》2021-2022學年期末試卷
- 視頻監(jiān)控系統(tǒng)原理與維修PPT課件
- 交叉口的vissim仿真與優(yōu)化畢業(yè)論文
- 危險源辨識一覽表
- 廣告宣傳類印刷服務項目方案純方案,124
- 醫(yī)用高值耗材目錄
- 高中英語語法 主謂一致(27張)ppt課件
- 采購管理實務習題答案項目二采購需求分析與計劃制定
- MSA-GRR數(shù)據(jù)自動生成工具
- H型鋼最新尺寸規(guī)格表大全(共3頁)
- 一層框架施工方案
- 工程變更申請單ECR
評論
0/150
提交評論