多線程實用全套PPT_第1頁
多線程實用全套PPT_第2頁
多線程實用全套PPT_第3頁
多線程實用全套PPT_第4頁
多線程實用全套PPT_第5頁
已閱讀5頁,還剩53頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第十章多線程第一頁,共58頁。1本講內(nèi)容(nèiróng)線程的概念(gàiniàn)10.2Java中多線程的編程線程的同步與死鎖第二頁,共58頁。線程的概念(gàiniàn)1.程序、進(jìn)程和線程1>程序是為完成(wánchéng)特定任務(wù)、用某種語言編寫的一組指令的集合。指一段靜態(tài)的代碼。2>進(jìn)程是程序的一次執(zhí)行過程,是系統(tǒng)進(jìn)行調(diào)度和資源分配的一個獨立單位。3>進(jìn)程中的一小段程序代碼稱為線程。第三頁,共58頁。2.線程的主要特點:1>不能以一個文件名的方式獨立存在在磁盤中;不能單獨執(zhí)行,只有在進(jìn)程啟動后才可啟動;各線程間共享進(jìn)程空間的數(shù)據(jù)(代碼與數(shù)據(jù)).2>線程是比進(jìn)程更小一級的執(zhí)行單元。3>一個進(jìn)程在其執(zhí)行過程中,可以產(chǎn)生多個線程,形成多條執(zhí)行線索。4>每個線程也有它自身的產(chǎn)生、存在和消亡的過程,也是一個動態(tài)的概念。5>一個線程有它自己的入口和出口,以及一個順序執(zhí)行的序列6>線程不能獨立存在,必須存在于進(jìn)程中,線程—線程創(chuàng)建、銷毀(xiāohuǐ)和切換的負(fù)荷遠(yuǎn)小于進(jìn)程,又稱為輕量級進(jìn)程(lightweightprocess)。系統(tǒng)負(fù)擔(dān)小,主要是CPU的分配。第四頁,共58頁。進(jìn)程是正在運行的一個程序程序:靜態(tài)對象--進(jìn)程:動態(tài)過程操作系統(tǒng)為每個進(jìn)程分配一段內(nèi)存空間,包括(bāokuò):代碼、數(shù)據(jù)以及堆棧等資源多任務(wù)的操作系統(tǒng)(OS)中,進(jìn)程切換對CPU資源消耗較大第五頁,共58頁。4.多線程1>多線程是指同時存在幾個執(zhí)行體,按幾條不同的執(zhí)行線索(xiànsuǒ)共同工作的情況。2>多線程實現(xiàn)單個進(jìn)程中的并發(fā)計算。3>各線程間共享進(jìn)程空間的數(shù)據(jù),并利用這些共享單元來實現(xiàn)數(shù)據(jù)交換、實時通信與必要的同步操作。4>多線程的程序能更好地表述和解決現(xiàn)實世界的具體問題,是計算機應(yīng)用開發(fā)和程序設(shè)計的一個必然發(fā)展趨勢。第六頁,共58頁。進(jìn)程(jìnchéng)與多線程單線程多線程進(jìn)程傳統(tǒng)進(jìn)程多線程進(jìn)程第七頁,共58頁。調(diào)度策略時間片搶占式:高優(yōu)先級的線程搶占CPUJava的調(diào)度方法(fāngfǎ)同優(yōu)先級線程組成先進(jìn)先出隊列,使用時間片策略對高優(yōu)先級,使用優(yōu)先調(diào)度的搶占式策略12第八頁,共58頁。與多線程1>Java語言的一個重要功能特點:就是內(nèi)置對多線程的支持,它使得編程人員可以很方便地開發(fā)出具有多線程功能,能同時(tóngshí)處理多個任務(wù)的功能強大的應(yīng)用程序。2>每個Java程序都有一個隱含的主線程每個Java程序都有一個主線程,對于APPLICATION程序,主線程是main()函數(shù)執(zhí)行的線索;對于Applet程序指揮瀏覽器加載并執(zhí)行Java小程序,要想實現(xiàn)多線程,必須在主線程中創(chuàng)建新的線程對象。3>線程的用途:利用它可以完成重復(fù)性的工作(如實現(xiàn)動畫、聲音等的播放);從事一次性較費時的初始化工作(如網(wǎng)絡(luò)連接、聲音數(shù)據(jù)文件的加載,但對圖像文件*.gif、*.jpeg在java中自動地在后臺載入、因而可不必設(shè)計圖像載入的線程);并行的執(zhí)行效果(一個進(jìn)程多個線程)。第九頁,共58頁。要想實現(xiàn)線程,必須在主線程中創(chuàng)建新的線程對象。Java語言使用Thread類及其子類的對象來表示線程,在它的一個完整的生命周期中通常要經(jīng)歷如下的五種狀態(tài):1>新建:當(dāng)一個Thread類或其子類的對象被聲明并創(chuàng)建時,新生的線程對象處于新建狀態(tài)2>就緒:處于新建狀態(tài)的線程被啟動后,將進(jìn)入線程隊列等待CPU時間片,此時它已具備了運行的條件3>運行:當(dāng)就緒的線程被調(diào)度并獲得處理器資源時,便進(jìn)入運行狀態(tài),run()方法定義了線程的操作和功能4>阻塞:在某種特殊情況下,被人為掛起或執(zhí)行輸入輸出操作時,讓出CPU并臨時中止自己的執(zhí)行,進(jìn)入阻塞狀態(tài)5>死亡:線程完成了它的全部工作或線程被提前強制性地中止stop()或destroy()線程死亡不具有繼續(xù)(jìxù)運行能力線程死亡有兩個原因:___正常執(zhí)行的線程完成它的全部工作,即執(zhí)行完run()方法的最后一句并退出___線程被強制終止,如stop()方法、destroy()方法第十頁,共58頁。線程的生命周期第十一頁,共58頁。線程的生命周期(續(xù))Newborn:線程已創(chuàng)建,但尚未執(zhí)行Runnable:(就緒)線程已被調(diào)度,按優(yōu)先級和先到先服務(wù)原則在隊列中排隊等待CPU時間片資源Runnnig:正在運行Blocked:(阻塞)因某事件或睡眠而被暫時性地掛起Dead:正常(zhèngcháng)/強行中斷,退出運行狀態(tài)第十二頁,共58頁。線程狀態(tài)(zhuàngtài)新建狀態(tài)newThread(..)就緒狀態(tài)start()等待狀態(tài)執(zhí)行狀態(tài)I/Osleep()CPU調(diào)度run()結(jié)束stop()yield()消亡

I/O完成sleep時間到第十三頁,共58頁。Java對多線程的支持(zhīchí)提供對多線程的支持Thread類start(),stop(),run()Runnable接口(jiēkǒu)實現(xiàn)多線程的兩種編程方法繼承Thread類實現(xiàn)Runnable接口(jiēkǒu)第十四頁,共58頁。Thread類Thread類綜合了Java程序中一個線程需要擁有的屬性和方法當(dāng)生成一個Thread類的對象后,一個新的線程誕生了。每個線程都是通過目標(biāo)對象的方法run()來完成其操作的。方法run()稱為線程體(線程方法)。提供(tígōng)線程體的目標(biāo)對象是在初始化一個線程時指明的。任何實現(xiàn)了Runnable接口(實現(xiàn)run()方法)的類實例都可以作為線程的目標(biāo)對象。第十五頁,共58頁。方法(fāngfǎ)之一:繼承Thread類Thread類的重要(zhòngyào)方法:run()定義線程的具體操作系統(tǒng)調(diào)度此線程時自動執(zhí)行初始時無具體操作內(nèi)容如何編程呢?-繼承(jìchéng)Thread類,定義run()方法第十六頁,共58頁。Thread類構(gòu)造函數(shù)Thread();Thread(Stringthreadname);指定線程實例名線程的優(yōu)先級控制三個常量(chángliàng):MAX_PRIORITY10;MIN_PRIORITY1;NORM_PRIORITY5;getPriority()返回線程優(yōu)先值setPriority(intnewPriority)改變線程的優(yōu)先級線程創(chuàng)建時繼承父線程的優(yōu)先級第十七頁,共58頁。Thread類的有關(guān)(yǒuguān)方法voidstart():由Newborn到Runnable啟動線程StringgetName():返回線程的名稱run():線程在被調(diào)度時執(zhí)行的操作(cāozuò)staticvoidsleep(指定時間毫秒):令當(dāng)前活動線程在指定時間段內(nèi)放棄對CPU控制,使其他線程有機會被執(zhí)行,時間到后重排隊產(chǎn)生例外InterruptedException用try塊調(diào)用sleep(),用catch塊處理例外第十八頁,共58頁。Thread類的有關(guān)(yǒuguān)方法(續(xù))suspend():掛起線程,處于(chǔyú)阻塞狀態(tài)resume():恢復(fù)掛起的線程,重新進(jìn)入就緒隊列排隊?wèi)?yīng)用:可控制某線程的暫停與繼續(xù)方法:設(shè)一狀態(tài)變量suspendStatus=false(初始)暫停:if(!suspendStatus) {T.suspend();suspendStatus=true;}繼續(xù):if(suspendStatus) {T.resume();suspendStatus=false;}第十九頁,共58頁。Thread類的有關(guān)(yǒuguān)方法(續(xù))staticvoidyield():對正在執(zhí)行的線程若就緒隊列中有與當(dāng)前線程同優(yōu)先級的排隊線程,則當(dāng)前線程讓出CPU控制權(quán),移到隊尾若隊列中沒有同優(yōu)先級的線程,忽略此方法stop():強制線程生命期結(jié)束(jiéshù)booleanisAlive():返回boolean,表明是否線程還存在staticcurrentThread():返回當(dāng)前線程

第二十頁,共58頁。生成與運行(yùnxíng)線程–方法1MyThreadmt=newMyThread();mt.start();

classMyThreadextendsThread{publicvoidrun(){線程體…}}執(zhí)行run()方法第二十一頁,共58頁。建立(jiànlì)線程線程控制(虛擬CPU)線程代碼被操作數(shù)據(jù)Thread類的子類的實例(mt)Thread類的子類提供的run方法Thread子類實例(mt)第二十二頁,共58頁。Thread類方法(fāngfǎ)總結(jié)啟動(qǐdòng)線程:start()有關(guān)線程執(zhí)行的控制:stop()、suspend()、resume()有關(guān)調(diào)度控制Thread.sleep(10);//低優(yōu)先級的線程也可以獲得執(zhí)行Thread.yield();//同優(yōu)先級的線程可以獲得執(zhí)行suspend();//暫停本線程第二十三頁,共58頁。for(inti=0;i<NUMRUNNERS;i++){if(updateThread.加鎖1(臨界區(qū)-方法)staticvoidyield():對正在執(zhí)行的線程謝謝(xièxie)觀看多個線程對內(nèi)存、數(shù)據(jù)(shùjù)的共享,會造成操Thread(Runnable,String)同優(yōu)先級線程組成先進(jìn)先出隊列,使用時間片策略Producerp1=newProducer(c,1);//Producer線程1>不能以一個文件名的方式獨立存在在磁盤中;updateThread=newThread(this,"ThreadRace");synchronized//創(chuàng)建繪圖線程,并設(shè)優(yōu)先級為3wait();//條件不符合,則waitpublicvoidrun(){方法(fāngfǎ)之二:RunnableRunnable接口自定義類實現(xiàn)(shíxiàn)Runnable接口使用Thread類的另一構(gòu)造函數(shù):Thread(Runnable,String)用實現(xiàn)(shíxiàn)了Runnable接口的類的對象中所定義的run()方法,來覆蓋新創(chuàng)建的線程對象的run()方法使用start()啟動線程第二十四頁,共58頁。方法(fāngfǎ)之二:Runnable(續(xù))例:classAimplementsRunnable{ publicvoidrun(){….}}classB{ publicstaticvoidmain(String[]arg){ Runnablea=newA(); Threadt=newThread(a); t.start(); } }第二十五頁,共58頁。建立(jiànlì)線程例publicclassThreadTest{publicstaticvoidmain(String[]args){Job1j=newJob1();Threadt1=newThread(j);t1.start();}}classJob1implementsRunnable{inti=1;publicvoidrun(){while(i<50){System.out.println(i++);}}}第二十六頁,共58頁。建立(jiànlì)線程線程控制(虛擬CPU)線程代碼被操作數(shù)據(jù)Thread的實例(t1)由實現(xiàn)了Runnable接口的類(Job1)提供—run方法實現(xiàn)Runnable接口的類(Job1)的實例(j)第二十七頁,共58頁。

生成(shēnɡchénɡ)與運行線程–方法2classMyRunimplementsRunnable{publicvoidrun(){線程體…}}MyRunmr=newMyRun();Threadt1=newThread(mr);t1.start();//Thread實例(shílì)用于線程控制適合于:定義run()方法的類必須是其他類或其他類的子類。第二十八頁,共58頁。方法(fāngfǎ)之二:Runnable(續(xù))兩種方法的選擇當(dāng)需要從其他類,如Applet類繼承時,使用Runnable接口(jiēkǒu)當(dāng)編寫簡單的程序時,可考慮使用繼承Thread類具體運行結(jié)果(線程調(diào)度)與平臺有關(guān)第二十九頁,共58頁。publicclassRunnerextendsThread{//賽跑者線程類

publicinttick=1;publicvoidrun(){while(tick<40000000)tick++;}}//Runner.java//RaceApplet是一個實現(xiàn)了多線程的AppletpublicclassRaceAppletextendsAppletimplementsRunnable{finalstaticintNUMRUNNERS=2;//定義賽跑線程的個數(shù)

finalstaticintSPACING=20;

//聲明兩個賽跑線程

Runner[]runners=newRunner[NUMRUNNERS];

//聲明一個畫圖線程

ThreadupdateThread=null;第三十頁,共58頁。publicvoidinit(){//重載Applet的init()方法(fāngfǎ)for(inti=0;i<NUMRUNNERS;i++){runners[i]=newRunner();//創(chuàng)建賽跑線程線程runners[i].setPriority(i+1);//設(shè)優(yōu)先級first=1,second=2}if(updateThread==null){ //創(chuàng)建繪圖線程,并設(shè)優(yōu)先級為3updateThread=newThread(this,"ThreadRace");updateThread.setPriority(NUMRUNNERS+1);}addMouseListener(newMyAdapter());//注冊事件監(jiān)聽者}//endofinit()第三十一頁,共58頁。//內(nèi)部事件監(jiān)聽者類,監(jiān)聽鼠標(biāo)事件classMyAdapterextendsMouseAdapter{//鼠標(biāo)點擊后,開始賽跑及繪制(huìzhì)線程publicvoidmouseClicked(MouseEventevt){if(!updateThread.isAlive())updateThread.start();//啟動繪制(huìzhì)線程for(inti=0;i<NUMRUNNERS;i++){if(!runners[i].isAlive())runners[i].start();//啟動賽跑線程}}}//endofclassMyAdapter第三十二頁,共58頁。publicvoidpaint(Graphicsg){//paint()方法中繪制(huìzhì)框架………}//endofpaint()//update()方法中繪制(huìzhì)賽跑者的進(jìn)度publicvoidupdate(Graphicsg){for(inti=0;i<NUMRUNNERS;i++){//畫兩條線g.drawLine(SPACING,(i+1)*SPACING,SPACING+(runners[i].tick)/100000,(i+1)*SPACING);}}//endofupdate()第三十三頁,共58頁。publicvoidrun(){//實現(xiàn)Runnable接口的run()方法while(true){repaint();//重新繪制,自動調(diào)用update()方法try{Thread.sleep(10);//休眠,把執(zhí)行機會(jīhuì)讓給低優(yōu)先級線程}catch(InterruptedExceptione){}}}//endofrun()publicvoidstop(){//重載Applet的stop()方法for(inti=0;i<NUMRUNNERS;i++){if(runners[i].isAlive())runners[i]=null;//中止賽跑線程}if(updateThread.isAlive())updateThread=null;//中止繪圖線程}//endofstop()}第三十四頁,共58頁。線程的同步(tóngbù)與互斥問題的提出多個線程執(zhí)行的不確定性引起執(zhí)行結(jié)果的不穩(wěn)定如線程A:A1-A2 線程B:B1-B2多個線程對內(nèi)存、數(shù)據(jù)(shùjù)的共享,會造成操作的不完整性,會破壞數(shù)據(jù)(shùjù)。如push(a):i++;num[i]=a;pop():取出num[i];i--;第三十五頁,共58頁。線程的同步(tóngbù)與互斥問題的解決同步:用synchronized關(guān)鍵字前綴給針對共享資源的操作(cāozuò)加鎖;同步方法、同步塊synchronizedvoidpush();synchronizedintpop();臨界區(qū)實現(xiàn)機制:管程第三十六頁,共58頁。線程的同步(tóngbù)與互斥對象互斥鎖在Java中,每個對象有一個“互斥鎖”,該鎖可用來保證(bǎozhèng)在同一時刻只能有一個線程訪問該對象。鎖的使用過程(當(dāng)一個線程要操作一個對象時)準(zhǔn)備加鎖對象是否已加鎖加鎖進(jìn)入臨界區(qū)執(zhí)行操作解鎖否是第三十七頁,共58頁。線程的同步(tóngbù)與互斥加鎖1(臨界區(qū)-方法)synchronized方法名{…}進(jìn)入該方法時加鎖加鎖2(臨界區(qū)-代碼塊)方法名{….synchronized(this){…}//進(jìn)入該代碼段時加鎖….}一個(yīɡè)線程為某對象加鎖后,便對該對象具有了監(jiān)控權(quán)。第三十八頁,共58頁。線程的同步(tóngbù)與互斥線程間需協(xié)調(diào)與通訊(tōngxùn):生產(chǎn)者/消費者問題進(jìn)隊出隊生產(chǎn)者消費者第三十九頁,共58頁。線程的同步(tóngbù)與互斥wait()與notify()Object類的方法:publicfinalvoidwait():令當(dāng)前線程掛起并放棄管程,同步資源解鎖,使別的線程可訪問并修改共享資源,而當(dāng)前線程排隊等候再次對資源的訪問notify()喚醒正在排隊等待資源管程的線程中優(yōu)先級最高者,使之執(zhí)行并擁有資源的管程wait()+notify()+標(biāo)志變量:可協(xié)調(diào)(xiétiáo)、同步不同線程的工作第四十頁,共58頁。線程的同步(tóngbù)與互斥主線程線程1()線程2()操作對象共享數(shù)據(jù)(隊)synchronized同步方法1(生產(chǎn))wait()notify()synchronized同步方法2(消費)wait()notify()第四十一頁,共58頁。線程的同步(tóngbù)與互斥publicfinalvoidwait()方法在當(dāng)前(dāngqián)線程中調(diào)用方法:對象名.wait()使當(dāng)前(dāngqián)線程進(jìn)入等待(某對象)狀態(tài),直到另一線程對該對象發(fā)出notify(或notifyAll)為止。調(diào)用方法的必要條件:當(dāng)前(dāngqián)線程必須具有對該對象的監(jiān)控權(quán)(加鎖)當(dāng)前(dāngqián)線程將釋放對象監(jiān)控權(quán),然后進(jìn)入等待隊列(wait隊列)。在當(dāng)前(dāngqián)線程被notify后,要重新獲得監(jiān)控權(quán),然后從斷點處繼續(xù)代碼的執(zhí)行。第四十二頁,共58頁。線程的同步(tóngbù)與互斥publicfinalvoidnotify()方法在當(dāng)前(dāngqián)線程中調(diào)用方法:對象名.notify()功能:喚醒等待該對象監(jiān)控權(quán)的一個線程。調(diào)用方法的必要條件:當(dāng)前(dāngqián)線程必須具有對該對象的監(jiān)控權(quán)(加鎖)notifyAll()喚醒wait隊列中的所有線程,并把它門移入鎖申請隊列。第四十三頁,共58頁。線程狀態(tài)(zhuàngtài)新建狀態(tài)就緒狀態(tài)start()等待狀態(tài)執(zhí)行狀態(tài)CPU調(diào)度run()結(jié)束消亡等待狀態(tài)對象wait()池等待狀態(tài)對象lock池wait()notify()synchronized()解鎖

sleep()join()yield()第四十四頁,共58頁。線程調(diào)度(diàodù)publicstaticvoidsleep(long

millis)當(dāng)前進(jìn)程休眠指定時間publicstaticvoidyield()主動讓出CPU,重新排隊正在執(zhí)行(zhíxíng)的線程將CPU讓給其他具有相同優(yōu)先級的線程,自己進(jìn)入就緒狀態(tài)重新排隊publicfinalvoidjoin()等待某線程結(jié)束第四十五頁,共58頁。等待(děngdài)另一線程結(jié)束Runnableot=newotheeThread();Threadtt=newThread(ot);tt.start();…//執(zhí)行自己(zìjǐ)的工作try{tt.join();}catch(interruptedExceptione){}….//繼續(xù)做自己(zìjǐ)的事第四十六頁,共58頁。終止(zhōngzhǐ)線程publicclassRimplementRunnable{privatebooleantimeToQuit=false;//設(shè)標(biāo)記(biāojì)publicvoidrun(){while(!timeToQuit){…}}publicvoidstopRunning(){timeToQuit=true;}}publicclasstest{publicstaticvoidmain(String[]args){Runnabler=newR();Threadt=newThread(r);t.start();if(…)r.stopRunning();}}第四十七頁,共58頁。線程的同步(tóngbù)與互斥創(chuàng)建用戶的線程子類Producer:產(chǎn)生數(shù)據(jù)(存數(shù)據(jù));Consumer:消費數(shù)據(jù)(取數(shù)據(jù))CubbyHole類,共享數(shù)據(jù)區(qū),同步方法put(intvalue)方法intget()方法主類中創(chuàng)建共享數(shù)據(jù)對象(duìxiàng),并啟動兩線程第四十八頁,共58頁。classCubbyHole{privateintseq;//共享數(shù)據(jù)(shùjù)privatebooleanavailable=false;//條件標(biāo)志變量publicsynchronizedintget(){//取數(shù)據(jù)(shùjù)的同步方法get() while(available==false){ try{ wait();//條件不符合,則wait }catch(InterruptedExceptione){} } available=false;//修改條件 notify();//通知喚醒其他等待管程的線程 returnseq;//返回要取出的數(shù)值}//endofget()第四十九頁,共58頁。//存放數(shù)據(jù)(shùjù)的同步方法put()publicsynchronizedvoidput(intvalue){ while(available==true){ try{ wait();//條件不符合,則wait }catch(InterruptedExceptione){} } seq=value;//把共享變量修改為要放置的數(shù)據(jù)(shùjù) available=true;//修改條件 notify();//通知喚醒其他等待管程的線程}//endofput()}//endofclassCubbyHole第五十頁,共58頁。classProducerextendsThread{//生產(chǎn)者線程類privateCubbyHolecubbyhole;privateintnumber;publicProducer(CubbyHolec,intnumber){cubbyhole=c;this.number=number;}publicvoidrun(){//定義(dìngyì)run()方法for(inti=0;i<10;i++){//共產(chǎn)生10個cubbyhole.put(i);System.out.println("Producer#"+this.number+"put:"+i);try{sleep((int)(Math.random()

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論