![java面向?qū)ο蟮谑?Java線程_第1頁(yè)](http://file4.renrendoc.com/view12/M05/22/0D/wKhkGWXw-xKADDgkAADQXsNSQvQ289.jpg)
![java面向?qū)ο蟮谑?Java線程_第2頁(yè)](http://file4.renrendoc.com/view12/M05/22/0D/wKhkGWXw-xKADDgkAADQXsNSQvQ2892.jpg)
![java面向?qū)ο蟮谑?Java線程_第3頁(yè)](http://file4.renrendoc.com/view12/M05/22/0D/wKhkGWXw-xKADDgkAADQXsNSQvQ2893.jpg)
![java面向?qū)ο蟮谑?Java線程_第4頁(yè)](http://file4.renrendoc.com/view12/M05/22/0D/wKhkGWXw-xKADDgkAADQXsNSQvQ2894.jpg)
![java面向?qū)ο蟮谑?Java線程_第5頁(yè)](http://file4.renrendoc.com/view12/M05/22/0D/wKhkGWXw-xKADDgkAADQXsNSQvQ2895.jpg)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第十章Java線程什么是進(jìn)程、線程創(chuàng)立線程的兩種方法線程的生命周期線程的類型分析1.什么是進(jìn)程、線程進(jìn)程:當(dāng)前正在執(zhí)行的程序,稱為進(jìn)程(progress) 例如:在進(jìn)行網(wǎng)上購(gòu)物時(shí),可以邊聽(tīng)音樂(lè)、收發(fā)Mail、QQ聊天等多個(gè)程序在運(yùn)行??赏ㄟ^(guò)windows任務(wù)管理器查看。 每個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間,一個(gè)進(jìn)程中可以啟動(dòng)多個(gè)線程。比方在Windows系統(tǒng)中,一個(gè)運(yùn)行的exe就是一個(gè)進(jìn)程。
說(shuō)明:對(duì)于單CPU無(wú)法同時(shí)運(yùn)行多個(gè)進(jìn)程,只能交替輪流執(zhí)行多個(gè)程序。在某一時(shí)刻,CPU執(zhí)行的進(jìn)程其實(shí)只有一個(gè)。1.1進(jìn)程與線程在windows中可以通過(guò)任務(wù)管理器查看進(jìn)程說(shuō)明:CPU是一種非常珍貴的資源,它直接影響程序的運(yùn)行情況。線程線程是進(jìn)程中程序代碼的一個(gè)執(zhí)行序列,是一種比進(jìn)程更小的執(zhí)行單位,一個(gè)進(jìn)程可以包含多個(gè)線程;線程也是一個(gè)動(dòng)態(tài)的概念,包含產(chǎn)生、存在和消亡的過(guò)程;每個(gè)進(jìn)程都有一段專用的內(nèi)存區(qū)域,而線程間可以共享相同的內(nèi)存單元(包括代碼與數(shù)據(jù)),數(shù)據(jù)交換、實(shí)時(shí)通信、同步操作更方便。因此,線程得到廣泛應(yīng)用,例如:QQ等支持多線程是Java的重要特色,它提供了Thread類來(lái)實(shí)現(xiàn)多線程;Java中的線程可以認(rèn)為是由三局部組成的:虛擬CPU:封裝在類中,控制著整個(gè)線程的運(yùn)行;執(zhí)行的代碼:傳遞給Thread類,由Thread類控制順序執(zhí)行;處理的數(shù)據(jù):傳遞給Thread類,是在代碼執(zhí)行過(guò)程中所要處理的數(shù)據(jù)。1.2Java中的線程代碼數(shù)據(jù)虛擬CPU以前的程序:一個(gè)入口,語(yǔ)句序列,一個(gè)出口。程序依次執(zhí)行,這稱為單線程。1.3多線程publicclassSequentialExample{//例1程序片段 publicstaticvoidmain(Stringargs[]){
newSequential("A").run(); newSequential("B").run(); }}classSequential{
Stringname=null; publicSequential(Stringn){//構(gòu)造器 name=n; }
publicvoidrun(){ for(inti=0;i<3;i++){ try{
Thread.sleep(500);//休眠0.5秒
System.out.println("訪問(wèn):"+name);
} }}程序運(yùn)行結(jié)果訪問(wèn):A訪問(wèn):A訪問(wèn):A訪問(wèn):B訪問(wèn):B訪問(wèn):B多線程:CPU交替執(zhí)行程序序列。//例2程序片段publicclassMultiThreadExample{ publicstaticvoidmain(Stringargs[]){ newMyThread("A").start(); newMyThread("B").start(); }}classMyThreadextendsThread{ publicMyThread(Stringn){//構(gòu)造器 super(n); }
publicvoidrun(){ for(inti=0;i<3;i++){ try{
Thread.sleep(500);//休眠0.5秒
System.out.println("訪問(wèn):"+getName());
}catch(InterruptedExceptione){} }}程序運(yùn)行可能結(jié)果訪問(wèn):A訪問(wèn):B訪問(wèn):A訪問(wèn):B訪問(wèn):A訪問(wèn):B2.創(chuàng)立線程的兩種方法從前面的例2可以知道:創(chuàng)立線程,最重要的是實(shí)現(xiàn)其中的run(),run()決定了線程所做的工作,又稱為線程體。當(dāng)線程開(kāi)始時(shí),代碼publicvoidrun()被執(zhí)行可用以下兩種方法來(lái)創(chuàng)立線程類:繼承線程類Thread實(shí)現(xiàn)Runnable接口Thread類和Runnable接口都在java.lang包中,是默認(rèn)導(dǎo)入的,不必使用import語(yǔ)句??赏ㄟ^(guò)繼承Thread類,并重寫其中的run()方法來(lái)定義線程體,以實(shí)現(xiàn)線程的具體行為,然后創(chuàng)立該子類的對(duì)象,并啟動(dòng)線程。其步驟為:(1)擴(kuò)展類:2.1繼承線程類Threadpublicclass線程類名extendsThread{ ……
publicvoidrun(){ ……//編寫線程的代碼 }}(2)創(chuàng)立線程類對(duì)象(3)啟動(dòng)線程:線程類對(duì)象.start();注意:不要在程序中直接調(diào)用線程的run()方法;啟動(dòng)線程并不意味著線程可以立即得到執(zhí)行,這取決于線程資源的獲取情況和CPU的占有情況。Thread類的構(gòu)造方法:publicThread();publicThread(Runnabletarget);publicThread(Runnabletarget,Stringname);publicThread(Stringname);publicThread(ThreadGroupgroup,Stringname);…Threadt1=newThread(pp1);其中:target表示run()所在類,name是線程(組)名Thread類的常用方法:voidrun():線程所執(zhí)行的代碼voidstart():?jiǎn)?dòng)線程voidsleep(longmilis):讓線程睡眠一段時(shí)間,此期間線程不消耗CPU資源voidinterrupt():中斷線程booleanisAlive():判斷線程是否處于活動(dòng)狀態(tài)(即已調(diào)用start)staticThreadcurrentThread():返回當(dāng)前線程對(duì)象的引用voidsetName(StringthreadName):改變線程的名字StringgetName():獲得線程的名字Thread類的常用方法(續(xù)):voidjoin([long
millis[,int
nanos]]):等待線程結(jié)束staticvoidyield():暫停當(dāng)前線程,讓其他線程執(zhí)行voidsetDaemon(booleanon):設(shè)置為守護(hù)線程voidsetPriority(intp):設(shè)置線程的優(yōu)先級(jí)notify()/notifyAll()/wait():從Object繼承而來(lái),用于線程間通信 以下幾個(gè)方法出于平安問(wèn)題考慮,現(xiàn)已不推薦使用:voiddestroy():銷毀線程voidstop():終止線程的執(zhí)行voidsuspend()/voidresume():掛起/恢復(fù)線程//例3用繼承Thread類方法創(chuàng)立線程publicclassPingPong1extendsThread{ privateintdelay; privateStringmessage; publicPingPong1(Stringm,intr){ message=m; delay=r; } publicvoidrun(){ try{ for(;;){ System.out.println(message); sleep(delay);//休眠 } }catch(InterruptedExceptione){ return; } } publicstaticvoidmain(String[]args){ PingPong1t1=newPingPong1("ping",500); PingPong1t2=newPingPong1("pong",1000); t1.start(); t2.start(); }}程序運(yùn)行結(jié)果(每次可能不同)pingpongpingpongpingpingpongpingPing…任何類都可以實(shí)現(xiàn)Runnable接口,而這個(gè)類的實(shí)例將用一個(gè)線程來(lái)調(diào)用,啟動(dòng)該類的run()方法。Runnable接口只有一個(gè)run()方法,其作用和Thread類的run()方法相同。創(chuàng)立步驟為:(1)定義目標(biāo)類:2.2實(shí)現(xiàn)Runnable接口publicclasspingpong2
implementsRunnable{ ……
publicvoidrun(){ ……//編寫線程的代碼 }}(2)不能直接創(chuàng)立目標(biāo)類對(duì)象并運(yùn)行它,而是應(yīng)該以目標(biāo)類為參數(shù)創(chuàng)立Thread類的對(duì)象,例如:PingPong2pp1=newPingPong2(“ping”,500));Threadt1=newThread(pp1);(3)啟動(dòng)線程:以目標(biāo)類為參數(shù)創(chuàng)立Thread類的對(duì)象.start(); 例如:t1.start();例4與例3的功能類似,只是使用了接口方法//例4利用接口Runnalbe方法創(chuàng)立線程publicclassPingPong2implementsRunnable{ privateintdelay; privateStringmessage; publicPingPong2(Stringm,intr){ message=m; delay=r; }//例4利用接口Runnalbe方法創(chuàng)立線程 publicvoidrun(){ try{ for(;;){ System.out.println(message); Thread.sleep(delay);//休眠 } }catch(InterruptedExceptione){ return; } } publicstaticvoidmain(String[]args){ PingPong2pp1=newPingPong2("ping",500); PingPong2pp2=newPingPong2("pong",1000); Threadt1=newThread(pp1); Threadt2=newThread(pp2); t1.start(); t2.start(); }}程序運(yùn)行結(jié)果(每次可能不同)pingpongpingpongpingpingpongpingpingpongping…練習(xí)線程的創(chuàng)立分別用兩種方法創(chuàng)立線程:〔1〕繼承Thread類,要求線程體輸出“由繼承Thread類創(chuàng)立線程?!薄?〕實(shí)現(xiàn)Runnable接口,要求線程體輸出“由實(shí)現(xiàn)Runnable接口創(chuàng)立線程?!庇衫^承Thread類創(chuàng)立線程的方法簡(jiǎn)單方便,可以直接操作線程,無(wú)需使用Thread.currentThread()。但不能再繼承其他類;使用Runnable接口方法可以將CPU,代碼和數(shù)據(jù)分開(kāi),形成清晰的模型;還可以從其他類繼承;保持程序風(fēng)格的一致性。2.3兩種方法的比較3.線程棧模型與線程的變量要理解線程調(diào)度的原理,以及線程執(zhí)行過(guò)程,必須理解線程棧模型。線程棧是指某時(shí)刻時(shí)內(nèi)存中線程調(diào)度的棧信息,當(dāng)前調(diào)用的方法總是位于棧頂。
3.線程棧模型與線程的變量當(dāng)程序執(zhí)行到t.start()時(shí),程序多出一個(gè)分支〔增加了一個(gè)調(diào)用棧B〕,這樣,棧A、棧B并行執(zhí)行。例5Join的應(yīng)用classMyRunnableimplementsRunnable{ Stringname; MyRunnable(Stringstr){ name=str; } publicvoidrun(){//Runnable接口中方法 for(inti=0;i<=10;i++) System.out.println(name+""+i); } publicstaticvoidmain(String[]args)throwsInterruptedException{ MyRunnablemyr=newMyRunnable("myThread"); Threadt=newThread(myr);//創(chuàng)立線程 t.start();//啟動(dòng) t.join(); System.out.println("run()方法執(zhí)行完后線程狀態(tài):"+t.isAlive()); }}舉例:創(chuàng)立線程,求兩個(gè)數(shù)之間所有整數(shù)之和classSumThreadextendsThread{ intvar1,var2; longsum; SumThread(inti1,inti2){ var1=i1; var2=i2; } longgetSum(){ returnsum; } publicvoidrun(){//run()方法
for(inti=var1;i<=var2;i++) sum+=i; }}publicclassThread3{ publicstaticvoidmain(String[]args)throwsException{ SumThreadst=newSumThread(1,1000); st.start(); System.out.println(st.getSum());
}}結(jié)果:0classSumThreadextendsThread{ intvar1,var2; longsum; SumThread(inti1,inti2){ var1=i1; var2=i2; } longgetSum(){ returnsum; } publicvoidrun(){//run()方法
for(inti=var1;i<=var2;i++) sum+=i; }}publicclassThread3{ publicstaticvoidmain(String[]args)throwsException{ SumThreadst=newSumThread(1,1000); st.start(); st.join();//主線程main等待st線程結(jié)束
System.out.println(st.getSum()); }}結(jié)果:500500改進(jìn)版本4.線程的生命周期新建死亡新建狀態(tài):當(dāng)一個(gè)線程類實(shí)例被創(chuàng)立時(shí),線程處于新建狀態(tài),此時(shí)的線程已經(jīng)被初始化,并分配了資源 例如:ThreadmyThread=newMyThreadClass();就緒狀態(tài):已具備運(yùn)行條件,進(jìn)入線程隊(duì)列,排隊(duì)等待CPU。一旦獲得CPU使用權(quán),就可進(jìn)入運(yùn)行狀態(tài) 例如:myThread.start();運(yùn)行狀態(tài):當(dāng)處于就緒狀態(tài)的線程被調(diào)度獲得CPU資源時(shí),就進(jìn)入了運(yùn)行狀態(tài)。定義在線程體中的run()方法被調(diào)用,從方法體的第一條語(yǔ)句開(kāi)始順序執(zhí)行;阻塞狀態(tài):處于運(yùn)行狀態(tài)的線程因事件的發(fā)生,而導(dǎo)致讓出CPU使用權(quán),并終止當(dāng)前執(zhí)行,進(jìn)行阻塞狀態(tài)。線程的生命周期有五種狀態(tài): 線程由運(yùn)行狀態(tài)進(jìn)入阻塞狀態(tài)包含以下幾種情況:調(diào)用了該線程的sleep()方法。等待其休眠指定時(shí)間之后,自動(dòng)脫離阻塞狀態(tài);等待I/O操作完成。一旦I/O操作完成,系統(tǒng)自己調(diào)用特定的指令使該線程恢復(fù)可運(yùn)行狀態(tài);調(diào)用wait()方法。調(diào)用notify()或notifyAll()方法可回到運(yùn)行狀態(tài);調(diào)用suspend()方法。調(diào)用resume()方法可恢復(fù)線程的執(zhí)行;死亡狀態(tài):線程通過(guò)以下兩種途徑進(jìn)入死亡狀態(tài):自然終止:正常運(yùn)行run()方法后終止;異常終止:調(diào)用stop()方法讓一個(gè)線程終止運(yùn)行。sleep():使一個(gè)線程在特定時(shí)間休眠,具體格式:publicstaticvoidsleep(longmillisec);(單位:毫秒)publicstaticvoidsleep(longmillisec,intnanosec);
(后一參數(shù)的單位:納秒)yield():將CPU讓予其它線程。這將導(dǎo)致正在運(yùn)行的線程暫時(shí)停止,允許其他線程運(yùn)行;正在休眠或等待的線程可通過(guò)調(diào)用interrupt()方法中斷,這會(huì)導(dǎo)致拋出一個(gè)interruptedException異常;通過(guò)isInterrupted()方法,可以了解一個(gè)線程是否被中斷;join():調(diào)用某線程的該方法,將當(dāng)前線程與該線程“合并”,即等待該線程結(jié)束,再恢復(fù)當(dāng)前線程的運(yùn)行。5.線程的根本控制例6代碼://線程喚醒的例子publicclassThreadInterruptDemoextendsThread{ publicvoidrun(){ System.out.println("休息,勿擾!"); try{ sleep(3600000); }catch(InterruptedExceptione){ System.out.println("啊,誰(shuí)叫醒我的?"); } } publicstaticvoidmain(Stringargs[]){
ThreadInterruptDemot=newThreadInterruptDemo(); t.start(); errupt();//喚醒線程 }}程序運(yùn)行結(jié)果休息,勿擾!啊,誰(shuí)叫醒我的?例7代碼://線程的join()方法publicclassThreadJoinDemoextendsThread{ publicstaticvoidmain(Stringargs[]){
MyRunnermyr=newMyRunner(); Threadt=newThread(myr); t.start(); try{
t.join(); }catch(InterruptedExceptione){ } for(inti=0;i<5;i++){ System.out.println("主線程:"+i); } }}classMyRunnerimplementsRunnable{
publicvoidrun(){ for(inti=0;i<5;i++) System.out.println("子線程:"+i); }}程序運(yùn)行結(jié)果子線程:0子線程:1子線程:2子線程:3子線程:4主線程:0主線程:1主線程:2主線程:3主線程:4//例8線程狀態(tài)轉(zhuǎn)換publicclassThreadStatusDemo{ publicstaticvoidmain(Stringargs[]){ MyRunnerr=newMyRunner(); Threadt=newThread(r);//新建狀態(tài) t.start();//啟動(dòng)狀態(tài) }}classMyRunnerimplementsRunnable{
publicvoidrun(){//運(yùn)行狀態(tài) for(inti=0;i<20;i++){ if(i%5==0&&i!=0){ try{ Thread.sleep(3000);//阻塞狀態(tài) }catch(InterruptedExceptione){ } } System.out.println("No."+i);//運(yùn)行狀態(tài) } }}程序運(yùn)行結(jié)果(當(dāng)為5的倍數(shù)時(shí)休眠3秒鐘)No.0No.1No.2No.3No.4No.5No.6……No.18No.19線程可以劃分為兩種類型:用戶線程(第1種)由用戶〔程序員〕創(chuàng)立在前臺(tái)執(zhí)行當(dāng)用戶線程運(yùn)行時(shí),JVM不會(huì)退出但在所有用戶線程都執(zhí)行完畢時(shí),JVM將終止所有守護(hù)線程(包括垃圾收集器),然后退出主線程是用main()方法創(chuàng)立的6.線程的類型守護(hù)線程(第2種):是為其它線程提供效勞的線程,它一般應(yīng)該是一個(gè)獨(dú)立的線程,它的run()方法是一個(gè)無(wú)限循環(huán);它們通常在后臺(tái)執(zhí)行,例如:定時(shí)器、垃圾回收器都是守護(hù)線程;某些用戶創(chuàng)立的線程會(huì)通過(guò)調(diào)用setDaemon()方法在后臺(tái)運(yùn)行。使用守護(hù)線程的本卷須知:(1)thread.setDaemon(true)必須在thread.start()之前設(shè)置,否那么會(huì)跑出一個(gè)IllegalThreadStateException異常。不能把正在運(yùn)行的常規(guī)線程設(shè)置為守護(hù)線程。
(2)在Daemon線程中產(chǎn)生的新線程也是Daemon的。
(3)局部任務(wù)不適合分配給Daemon來(lái)進(jìn)行效勞,比方IIO讀寫。
例9代碼://守護(hù)線程的例子publicclassDaemonThreadextendsThread{
publicvoidrun(){ while(true){ System.out.println("守護(hù)線程正在運(yùn)行..."); } } publicstaticvoidmain(Stringargs[]){
DaemonThreaddt=newDaemonThread(); dt.setDaemon(true);//設(shè)置為后臺(tái)線程 dt.start(); }}程序運(yùn)行結(jié)果守護(hù)線程正在運(yùn)行...守護(hù)線程正在運(yùn)行...守護(hù)線程正在運(yùn)行...守護(hù)線程正在運(yùn)行...守護(hù)線程正在運(yùn)行...…...問(wèn)題:該線程最終能否自動(dòng)終止?例10代碼://文件輸出的守護(hù)線程任務(wù)importjava.io.*;classTestRunnableimplementsRunnable{publicvoidrun(){try{Thread.sleep(1000);//守護(hù)線程阻塞1秒后運(yùn)行
Filef=newFile(“F://daemon.txt");FileOutputStreamos=newFileOutputStream(f,true);os.write("daemon".getBytes());}catch(IOExceptione1){e1.printStackTrace();}catch(InterruptedExceptione2){e2.printStackTrace();}}}例10代碼〔續(xù)〕:publicclassTestDemo2{publicstaticvoidmain(String[]args)throwsInterruptedException{Runnabletr=newTestRunnable();Threadthread=newThread(tr);
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 詳盡多條款單項(xiàng)勞務(wù)分包合同
- 保險(xiǎn)服務(wù)居間合同
- 工業(yè)廠房租賃合同
- 建筑工程款轉(zhuǎn)讓協(xié)議書
- 裝卸運(yùn)輸服務(wù)合同
- 智能科技產(chǎn)品開(kāi)發(fā)合作合同
- 個(gè)人果樹(shù)承包合同
- 管理軟件系統(tǒng)買賣合同書
- 美術(shù)老師教學(xué)成果保護(hù)協(xié)議
- 項(xiàng)目策劃服務(wù)合同
- 2024屆廣東省深圳市中考物理模擬試卷(一模)(附答案)
- 前庭功能鍛煉科普知識(shí)講座
- 信永中和線上測(cè)評(píng)題庫(kù)
- 供應(yīng)鏈戰(zhàn)略布局與區(qū)域拓展案例
- 上海話培訓(xùn)課件
- 注塑車間績(jī)效考核方案
- 初中英語(yǔ)閱讀理解專項(xiàng)練習(xí)26篇(含答案)
- LS/T 1234-2023植物油儲(chǔ)存品質(zhì)判定規(guī)則
- 如何培養(yǎng)孩子的自主學(xué)習(xí)能力
- 【新能源汽車企業(yè)的財(cái)務(wù)風(fēng)險(xiǎn)控制研究:以比亞迪公司為例15000字】
- 核心素養(yǎng)導(dǎo)向的作業(yè)設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論