《多線程程序設(shè)計》PPT課件.ppt_第1頁
《多線程程序設(shè)計》PPT課件.ppt_第2頁
《多線程程序設(shè)計》PPT課件.ppt_第3頁
《多線程程序設(shè)計》PPT課件.ppt_第4頁
《多線程程序設(shè)計》PPT課件.ppt_第5頁
已閱讀5頁,還剩54頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、Xueping Shen,1,java多線程程序設(shè)計,Xueping Shen,2,想象一下,如果我們想要從Internet上下載一段很長的視頻或者音頻片段,如果我們可以把下載任務(wù)放在一個獨立的線程里實現(xiàn),我們在下載開始之后很快就可以觀看這個片段了,而不是必須等全部下載完成才可以觀看。 此外,多線程的執(zhí)行還可以允許許多用戶同時訪問一個公共的數(shù)據(jù)庫,這個特性對于類似庫存管理和機票預(yù)定這樣的系統(tǒng)有時候顯得非常有用。 為了防止由于多個用戶同時讀取和寫入公共數(shù)據(jù)庫而造成的數(shù)據(jù)破壞,多線程還需要在對象上設(shè)置鎖。這樣一個時刻只有一個線程能夠修改一個對象的狀態(tài)。,Xueping Shen,3,如何實踐對正在

2、下載的視頻進行同時觀看; 機票預(yù)訂; 并發(fā)的處理。,Xueping Shen,4,主要知識點,線程的概念 線程的調(diào)度 創(chuàng)建和啟動線程 Thread線程類、 Runnable接口 多個線程的同步 線程之間的通信,Xueping Shen,5,多線程,程序:是一段靜態(tài)的代碼,它是應(yīng)用程序執(zhí)行的藍本。 進程:是程序的一次動態(tài)執(zhí)行過程,它對應(yīng)了從代碼加載、執(zhí)行到執(zhí)行完畢的一個完整過程,也是進程本身從產(chǎn)生、發(fā)展至消亡的過程。 目前所流行的操作系統(tǒng)中,大部分都是支持多任務(wù)的(如Windows 3.X,Windows NT,Windows 95,OS/2及UNIX的各個版本),這實際就是一種多進程的概念每一

3、個任務(wù)就是一個進程。 線程:比進程更小的執(zhí)行單位。一個進程在執(zhí)行過程中,為了同時完成多項操作,可以產(chǎn)生多個線程,形成多條執(zhí)行線索。每個線程都有它自身的產(chǎn)生、存在和消亡的過程。,Xueping Shen,6,線程和進程之間的關(guān)系:,多進程環(huán)境中每一個進程既包括其所要執(zhí)行的指令, 也包括執(zhí)行指令所需的任何系統(tǒng)資源, 如CPU、內(nèi)存空間、I/O端口等,不同進程所占用的系統(tǒng)資源相對獨立; 線程是比進程單位更小的執(zhí)行單位,多線程環(huán)境中每一個線程都隸屬于某一進程,由進程觸發(fā)執(zhí)行,在系統(tǒng)資源的使用上,屬于同一進程的所有線程共享該進程的系統(tǒng)資源; 與進程不同的是線程本身即沒有入口,也沒有出口,其自身也不能獨立

4、運行,它棲身于某個進程之中,由進程啟動運行,完成其任務(wù)后,自動終止,也可以由進程使之強制終止。,Xueping Shen,7,多線程程序設(shè)計:,是指單個程序包含并發(fā)執(zhí)行的多個線程。當多線程程序執(zhí)行時,該程序?qū)?yīng)的進程中就有多個控制流在同時執(zhí)行,即具有并發(fā)執(zhí)行的多個線程; 例如: PV操作 Web Server接受客戶端的請求問題 銀行問題 網(wǎng)絡(luò)聊天(一對多)程序,Xueping Shen,8,一個多線程的例子:Test.java 此程序創(chuàng)建兩個線程,分別執(zhí)行存取款操作,并規(guī)定 每次存款25000元,每次取款50000元。,Xueping Shen,9,進程、線程示意圖,Xueping Shen

5、,10,為什么要使用多線程?,由于線程在程序內(nèi)部,多個線程共享一些系統(tǒng)的開銷,而線程本身的數(shù)據(jù)通常只有微處理器的寄存器數(shù)據(jù),以及一個供程序執(zhí)行時使用的堆棧。 例如線程之間共享相同的內(nèi)存單元(代碼和數(shù)據(jù)),因此在線程間切換,不需要很大的系統(tǒng)開銷,所以線程之間的切換速度遠遠比進程之間快,線程之間的通信也比進程通信快的多。 多個線程輪流搶占CPU資源而運行時,從微觀上講,一個時間里只能有一個作業(yè)被執(zhí)行,在宏觀上可使多個作業(yè)被同時執(zhí)行,即等同于要讓多臺計算機同時工作,使系統(tǒng)資源特別是CPU的利用率得到提高,從而可以提高整個程序的執(zhí)行效率。,Xueping Shen,11,線程運行環(huán)境,Xueping

6、Shen,12,每一個進程就是一個應(yīng)用程序。有自己的入口和出口。 多進程環(huán)境中每一個進程既包括其所要執(zhí)行的指令, 也包括了執(zhí)行指令所需的任何系統(tǒng)資源, 如CPU、內(nèi)存空間、I/O端口等; 不同進程所占用的系統(tǒng)資源相對獨立。,多個線程可共同存在于一個應(yīng)用程序中。 多線程環(huán)境中每一個線程都隸屬于某一進程,由進程觸發(fā)執(zhí)行(沒有自己的入口和出口); 在系統(tǒng)資源的使用上,屬于同一進程的所有線程共享該進程的系統(tǒng)資源。,線程之間切換的速度比進程切換要快得多。,進程和線程的比較(總結(jié)),Xueping Shen,13,線程的調(diào)度(1),微觀上,在一臺只具有一個CPU的機器上,CPU在同一時間只能分配給一個線程

7、做一件事。 當有多于一個的線程工作時,在Java中,線程調(diào)度通常是搶占式(即哪一個線程先搶到CPU資源則先運行),而不是分時間片式。 一旦一個線程獲得執(zhí)行權(quán),這個線程將持續(xù)運行下去,直到它運行結(jié)束或因為某種原因而阻塞,或者有另一個高優(yōu)先級線程就緒(這種情況稱為低優(yōu)先級線程被高優(yōu)先級線程所搶占)。,Xueping Shen,14,線程的調(diào)度(2),所有被阻塞的線程按次序排列,組成一個阻塞隊列。例如: 因為需要等待一個較慢的外部設(shè)備,例如磁盤或用戶。 讓處于運行狀態(tài)的線程調(diào)用Thread.sleep()方法。 讓處于運行狀態(tài)的線程調(diào)用另一個線程的join()方法。 所有就緒但沒有運行的線程則根據(jù)其

8、優(yōu)先級排入一個就緒隊列。 當CPU空閑時,如果就緒隊列不空,就緒隊列中第一個具有最高優(yōu)先級的線程將運行。 當一個線程被搶占而停止運行時,它的運行態(tài)被改變并放到就緒隊列的隊尾; 一個被阻塞(可能因為睡眠或等待I/O設(shè)備)的線程就緒后通常也放到就緒隊列的隊尾。,Xueping Shen,15,線程的調(diào)度與優(yōu)先級,線程的調(diào)度是按: 其優(yōu)先級的高低順序執(zhí)行的; 同樣優(yōu)先級的線程遵循“先到先執(zhí)行的原則”; 線程優(yōu)先級:范圍 110 (10 級)。數(shù)值越大,級別越高 Thread 類定義的 3 個常數(shù): MIN_PRIORITY 最低(小)優(yōu)先級(值為1) MAX_PRIORITY 最高(大)優(yōu)先級(值為

9、10) NORM_PRIORITY 默認優(yōu)先級(值為5) 線程創(chuàng)建時,繼承父線程的優(yōu)先級。 常用方法: getPriority( ):獲得線程的優(yōu)先級 setPriority( ):設(shè)置線程的優(yōu)先級 ThreadPri.java,Xueping Shen,16,Xueping Shen,17,主線程,主線程: main( ) 方法Application 應(yīng)用程序 每當用java命令啟動一個Java虛擬機進程( Application 應(yīng)用程序),Java虛擬機就會創(chuàng)建一個主線程,該線程從程序入口main()方法開始執(zhí)行。 瀏覽器中加載的 Applet 主類Applet 小程序 多線程:在主線程

10、中創(chuàng)建 Thread 類或其子類對象時,就創(chuàng)建了一個線程對象。Programmer可以控制線程的啟動、掛起與終止。,Xueping Shen,18,public class Sample public void method1(String str) System.out.println(str); public void method2(String str) method1(str); public static void main(String args) Sample s=new Sample(); s.method2(hello); ,當我們運行java Sample命令時,java

11、虛擬機會給每個線程分配方 法調(diào)用棧,用于跟蹤每個線程調(diào)用方法的信息,同時方法調(diào)用棧 還用做線程的工作區(qū),方法局部變量會存放到方法調(diào)用棧中,Xueping Shen,19,線程的狀態(tài),在一個多線程運行環(huán)境中運行的線程可以有多種狀態(tài),也就是說一個線程在不同時刻會處于下列狀態(tài)之一: 新建、就緒、運行、阻塞、終止;,Xueping Shen,20,線程生命周期中的5種狀態(tài),新建:當一個 Thread 類或其子類對象被創(chuàng)建時,新產(chǎn)生的線程處于新建狀態(tài),此時它已經(jīng)有了相應(yīng)的內(nèi)存空間和其他資源。如: Thread myThread=new MyThreadClass( ); 就緒:調(diào)用 start( ) 方

12、法來啟動處于新建狀態(tài)的線程后,將進入線程隊列排隊等待 CPU 服務(wù),此時它已經(jīng)具備了運行的條件,一旦輪到它來享用 CPU 資源時,就可以脫離創(chuàng)建它的主線程,開始自己的生命周期。 運行:當就緒狀態(tài)的線程被調(diào)度并獲得處理器資源時,便進入運行狀態(tài)。每一個 Thread 類及其子類的對象都有一個重要的 run( ) 方法,當線程對象被調(diào)用執(zhí)行時,它將自動調(diào)用本對象的 run( ) 方法,從第一句開始順序執(zhí)行。Run( ) 方法定義了這個線程的操作和功能。,Xueping Shen,21,線程生命周期中的5種狀態(tài):,阻塞:一個正在執(zhí)行的線程暫停自己的執(zhí)行而進入的狀態(tài)。引起線程由運行狀態(tài)進入阻塞狀態(tài)的可能

13、情況: 該線程正在等待 I/O 操作的完成 調(diào)用了該線程的 sleep( ) 方法 調(diào)用了 wait( ) 方法 讓處于運行狀態(tài)的線程調(diào)用另一個線程的join()方法,Xueping Shen,22,線程生命周期中的5種狀態(tài):,對應(yīng)于不同進入阻塞狀態(tài)的情況,采取不同的方法使其回到就緒狀態(tài): I/O 操作:等待這個 I/O 操作完成后; sleep( ) 方法:等待其指定的休眠事件結(jié)束后,自動脫離阻塞狀態(tài); 調(diào)用 wait( ) 方法:調(diào)用 notify( ) 或 notifyAll( ) 方法;,Xueping Shen,23,線程生命周期中的5種狀態(tài):,終止: 自然終止:線程完成了自己的全部

14、工作 強制終止:在線程執(zhí)行完之前,調(diào)用 stop( ) 或 destroy( ) 方法終止線程,Xueping Shen,24,線程的狀態(tài)及轉(zhuǎn)換,Xueping Shen,25,創(chuàng)建一個新的線程,Java中的多線程是建立在Thread類,Runnable接口的基礎(chǔ)上的,通常有兩種辦法讓我們來創(chuàng)建一個新的線程: 創(chuàng)建一個Thread類,或者一個Thread子類的對象; 創(chuàng)建一個實現(xiàn)Runnable接口的類的對象;,Xueping Shen,26,name:線程的名稱,target:要運行的線程對象,group:線程組的名稱,stackSize:堆棧的大小,Thread類介紹,Xueping Sh

15、en,27,Thread類介紹,countStackFrames(); suspend(); resume(); stop(); stop(Throwableobj);,Xueping Shen,28,Thread類的常用方法,currentThread():返回當前運行的Thread對象。 setName():設(shè)置線程的名字。 getName():返回該線程的名字。 setPriority():設(shè)置線程優(yōu)先級。 getPriority():返回線程優(yōu)先級。 start():啟動一個線程。 run():線程體,由start()方法調(diào)用,當run()方法返回時,當前的線程結(jié)束。 stop():使

16、調(diào)用它的線程立即停止執(zhí)行。 isAlive():如果線程已被啟動并且未被終止,那么isAlive():返回true。如果返回false,則該線程是新創(chuàng)建或是已被終止的。,Xueping Shen,29,Thread類的常用方法,sleep(int n):使線程睡眠n毫秒,n毫秒后,線程可以再次運行。 yield():將CPU控制權(quán)主動移交到下一個可運行線程。 join():方法join()將引起現(xiàn)行線程等待,直至方法join所調(diào)用的線程結(jié)束。 suspend(): 使線程掛起,暫停運行。 resume() 恢復掛起的線程,使其處于可運行狀態(tài)(Runnable)。 wait(): notify(

17、): notifyAll():,suspend(); resume(); Stop(); 目前已經(jīng)不再使用。為什么?請看API.,Xueping Shen,30,因為Java線程的調(diào)度不是分時的,所以你必須確保你 的代碼中的線程會不時地給另外一個線程運行的機會。 有三種方法可以做到一點: 讓處于運行狀態(tài)的線程調(diào)用Thread.sleep()方法。 讓處于運行狀態(tài)的線程調(diào)用Thread.yield()方法。 讓處于運行狀態(tài)的線程調(diào)用另一個線程的join()方法。,Xueping Shen,31,sleep()和yield()的區(qū)別,這兩個方法都是靜態(tài)的實例方法。 yield()讓運行中的線程主動

18、放棄當前獲得的CPU處理機會,但不是使該線程阻塞,而是使之轉(zhuǎn)入就緒狀態(tài)。 yield()給相同優(yōu)先級或更高的線程運行機會,如果當前沒有存在相同優(yōu)先級的線程,則yield()什么都不做。而sleep()不會考慮線程的優(yōu)先級,會給其他線程運行的機會,因此也會給相同或更低優(yōu)先級線程運行機會。 sleep()使線程轉(zhuǎn)入阻塞狀態(tài),而yield()使線程轉(zhuǎn)入runnable狀態(tài)。 sleep()會有中斷異常拋出,而yiled()不拋出任何異常。 sleep()方法具有更好的可移植性,因為yield()的實現(xiàn)還取決于底層的操作系統(tǒng)對線程的調(diào)度策略。 對于yield()的主要用途是在測試階段,人為的提高程序的

19、并發(fā)性能,以幫助發(fā)現(xiàn)一些隱藏的并發(fā)錯誤,當程序正常運行時,則不能依靠yield方法提高程序的并發(fā)行能。,Xueping Shen,32,方法wait()與sleep() 方法一樣,都能使線程等待而停止運行,其區(qū)別在于sleep()方法不會釋放對象的鎖,而wait()方法進入等待時,可以釋放對象的鎖,因而別的線程能對這些加鎖的對象進行操作。所以,wait,notify和notifyAll都是與同步相關(guān)聯(lián)的方法,只有在synchronized方法中才可以用。 在不同步的方法或代碼中則使用sleep()方法使線程暫時停止運行。,Xueping Shen,33,線程類Thread中提供以下幾個版本的j

20、oin()方法。 使當前正在運行的線程暫停下來,等待指定的時間后 或等待調(diào)用該方法的線程結(jié)束后,再恢復運行。 public final void join()throws InterruptedException; public final void join(long millis,int nanos)throws InterruptedException; public final void join(long millis)throws InterruptedException;,join() 方法:,舉例:TestSubThread2.java,Xueping Shen,34,publ

21、ic void timeout() / 暫停該線程,等候其他線程(tt)結(jié)束 tt.join(); / 其他線程結(jié)束后,繼續(xù)進行該線程 ,join():方法join()將引起現(xiàn)行線程等待,直至方法join 所調(diào)用的線程結(jié)束。,Xueping Shen,35,Xueping Shen,36,將一個類定義為Thread的子類,那么這個類就可以 用來創(chuàng)建線程。 這個類中有一個至關(guān)重要的方法public void run,這個方法稱為線程體,它是整個線程的核心,線程所要完成任務(wù)的代碼都定義在線程體中,實際上不同功能的線程之間的區(qū)別就在于它們線程體的不同,舉例:ThreadTester.java Tes

22、tSubThread.java TestMyThread.java Example19_1.java UseThread.java,應(yīng)用線程類創(chuàng)建線程,Xueping Shen,37,TimePrinter.java,Xueping Shen,38,Thread.sleep()方法的使用,注意異常的拋出,Xueping Shen,39,Xueping Shen,40,Xueping Shen,41,Thead.yield()方法,Xueping Shen,42,主線程和其他線程共存,Xueping Shen,43,Xueping Shen,44,Thread.sleep()方法的使用,注意異常

23、的拋出,Xueping Shen,45,Xueping Shen,46,join()方法的使用,注意異常的拋出。保證了主線程最后結(jié)束,Xueping Shen,47,Xueping Shen,48,Xueping Shen,49,Xueping Shen,50,應(yīng)用Runnable接口創(chuàng)建線程,Runnable是Java中用以實現(xiàn)線程的接口,從根本 上講,任何實現(xiàn)線程功能的類都必須實現(xiàn)該接口。 Thread(Runnable target); Thread(Runnable target, String name); Runnable接口中只定義了一個方法就是run()方法,也就是線程體。,舉

24、例:TimePrinter1.java TestMyClassThread.java UseRunnable.java UseRunnable.html,Xueping Shen,51,Xueping Shen,52,Xueping Shen,53,Xueping Shen,54,因為Java只允許單繼承,如果一個類已經(jīng)繼承了Thread,就不能再繼承其他類。 比如對于Applet程序,由于必須繼承java. applet.Applet,因此就只能采取這種實現(xiàn)接口的方法。 特別是在除了run()方法以外,并不打算重寫Thread類的其它方法的情況下,以實現(xiàn)Runnable接口的方式生成新線程就

25、顯得更加合理了。,適用于采用實現(xiàn)Runnable接口方法的情況,Xueping Shen,55,終止線程,當線程執(zhí)行完run()方法,它將自然終止運行。 Thread有一個stop()方法,可以強制結(jié)束線程,但這種方法是不安全的。因此,在JDK1.2開始的版本中,stop()方法已經(jīng)被廢棄。 實際編程中,一般是定義一個標志變量,然后通過程序來改變標志變量的值,從而控制線程從run()方法中自然退出。,Xueping Shen,56,Xueping Shen,57,1.創(chuàng)建一個Thread類的子類 2.在子類中將希望該線程做的工作寫到run()里面 3.生成該子類的一個對象 4.調(diào)用該對象的start()方法 class MyThread extends Threa

溫馨提示

  • 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

提交評論