




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第8章Java的多線程本章內(nèi)容1線程及其創(chuàng)建2線程的調(diào)度3線程的同步與共享1什么是線程?線程是一個程序內(nèi)的順序控制流,使得一個程序具有能夠“同時”執(zhí)行多個任務的能力。線程與進程每個進程都有獨立的代碼和數(shù)據(jù)空間(進程上下文),進程切換的開銷大,不同進程間交換數(shù)據(jù)困難。線程:輕量的進程,同一類線程共享代碼和數(shù)據(jù)空間,線程切換的開銷小。多進程:在操作系統(tǒng)中能同時運行多個任務(程序)。多線程:在同一應用程序中有多個順序流同時執(zhí)行。線程可以理解為比進程更小的的程序單元。都具有并發(fā)執(zhí)行多任務的能力,線程包含在進程內(nèi)。多線程編程6/26/20232線程(Thread),也稱執(zhí)行上下文(ExecutionContext)包括:虛擬CPU線程體(Code)線程數(shù)據(jù)(Data)線程模型Java線程模型代碼數(shù)據(jù)虛擬CPU6/26/20233Java使用Thread類描述線程對象,該類定義在java.lang包中。在創(chuàng)建Thread對象的時候,一定要將線程體代碼“提交”給線程對象。這可以從線程類構造器看出來。Runnable接口,只要某個對象實現(xiàn)了Runnable接口的實現(xiàn),就可以提交給線程對象。由線程執(zhí)行該接口中封裝的方法:publicvoidrun();如何創(chuàng)建一個線程?6/26/20234使用Runnable接口(TestThread2.java)
可以將CPU,代碼和數(shù)據(jù)分開,形成清晰的模型;
還可以從其他類繼承;
保持程序風格的一致性。直接繼承Thread類(TestThread1.java)
不能再從其他類繼承;
編寫簡單,可以直接操縱線程,無需使用Thread.currentThread()。兩種創(chuàng)建線程方法的比較6/26/20235直接繼承Thread類publicclassTestThread1{publicstaticvoidmain(Stringargs[]){ Threadt1=newMyThread();
t1.start(); }}classMyThreadextendsThread{ publicvoidrun(){ for(inti=0;i<5;i++){ System.out.print(""+i); } System.out.println(); }}6使用Runnable接口publicclassTestThread2{publicstaticvoidmain(Stringargs[]){
MyThreadmyThread=newMyThread(5); Threadt1=newThread(myThread); t1.start(); }}classMyThreadimplementsRunnable{ privateintn; publicMyThread(intn){this.n=n;} publicvoidrun(){ for(inti=0;i<n;i++){System.out.println(""+i); try{Thread.sleep(500);//當前正在運行的線程睡500毫秒
}catch(InterruptedExceptione){} } }}7兩種方法的比較直接繼承Thread類 不能再從其他類繼承;
編寫簡單,可以直接操縱線程,無需使用Thread.currentThread()。使用Runnable接口 可以將CPU,代碼和數(shù)據(jù)分開,形成清晰的模型;
還可以從其他類繼承;
保持程序風格的一致性。若直接繼承Thread類,this即指當前線程;若使用Runnable接口,要獲得當前線程,就必須使用
Thread.currentThread()方法。publicstaticThreadcurrentThread()//返回對當前正在執(zhí)行的線程對象的引用。Example:ThreadTester.javaandThreadTester2.java8沒有保障的線程classThreadTestextendsThread{
publicvoidrun(){
System.out.println("sometingrunhere!");
}
publicvoidrun(Strings){
System.out.println("stringinrunis"+s);
}
publicstaticvoidmain(String[]args){
ThreadTesttt=newThreadTest();
tt.start();
tt.run("itwon'tautorun!");
}
}
輸出的結果比較有趣:
stringinrunisitwon'tautorun!
sometingrunhere!
9沒有保障的線程一旦調(diào)用start()方法,必須給JVM點時間,讓它配置進程。而在它配置完成之前,重載的run(Strings)方法被調(diào)用了,結果反而先輸出了“stringinrunisitwon'tautorun!”,這時tt線程完成了配置,輸出了“sometingrunhere!”。
這個結論是比較容易驗證的:
修改上面的程序,在tt.start();后面加上語句for(inti=0;i<10000;i++);這樣主線程開始執(zhí)行運算量比較大的for循環(huán)了,只有執(zhí)行完for循環(huán)才能運行后面的tt.run("itwon'tautorun!");語句。此時,tt線程和主線程并行執(zhí)行了,已經(jīng)有足夠的時間完成線程的配置!因此先到一步!修改后的程序運行結果如下:
sometingrunhere!
stringinrunisitwon'tautorun!
注意:這種輸出結果的順序是沒有保障的!不要依賴這種結論!
10沒有保障的線程
classThreadTestimplementsRunnable{
publicvoidrun(){
System.out.println(Thread.currentThread().getName());
}
publicstaticvoidmain(String[]args){
ThreadTesttt=newThreadTest();
Thread[]ts=newThread[10];
for(inti=0;i<ts.length;i++)
ts[i]=newThread(tt);
for(Threadt:ts)
t.start();
}
}
11沒有保障的線程在電腦上運行的結果是(每臺電腦運行結果會不同):
Thread-0
Thread-1
Thread-3
Thread-5
Thread-2
Thread-7
Thread-4
Thread-9
Thread-6
Thread-8
而且每次運行的結果都是不同的!繼續(xù)引用前面的話,一旦涉及到線程,其運行多半是沒有保障。這個保障是指線程的運行完全是由調(diào)度程序控制的,我們沒法控制它的執(zhí)行順序,持續(xù)時間也沒有保障,有著不可預料的結果。
12線程控制:啟動,start方法。終止,正常結束及stop方法。//stop方法已過時掛起和恢復,suspend和resume方法。//已過時睡眠,sleep方法。釋放執(zhí)行權,
yield方法。join方法。destroy方法。//已過時線程控制及線程狀態(tài)6/26/202313publicbooleanisAlive()//測試線程是否處于活動狀態(tài)。如果線程已經(jīng)啟動且尚未終止,則為活動狀態(tài)。在start()方法后,線程才真正“運行”了。良好的終止線程的手段應該是向線程發(fā)“中斷”通知,而不是直接調(diào)用stop方法。ThreadTerminateByFlag.java暫時阻止線程的執(zhí)行不主張使用suspend()方法來暫時阻止線程的執(zhí)行,不主張用resume()方法來恢復線程的執(zhí)行常用方法有:sleep()方法:當前線程掛起,一定時間后再運行join()方法:當前線程掛起,等待其他線程完成后再加入
yield()方法:當前線程讓步給其他線程ThreadJoin.java線程控制方法:掛起6/26/202314線程調(diào)度(分時time-slicing和搶先preemptive)JVM不保證線程調(diào)度的算法,所以線程實際的運行行為會有很大差別,不同的JVM調(diào)度實現(xiàn)有可能是不一樣的??梢允褂胹etPriority(int)方法來設置線程的優(yōu)先級。Java中用1-10表示運行的優(yōu)先等級,等級越高,表示越緊急,在同一時間片斷,有運行優(yōu)先權Thread類有三個有關線程優(yōu)先級的靜態(tài)常量:MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY設置線程優(yōu)先級的例子:TestThreadPriority.java但是并不是所有的jvm的調(diào)度都這樣,因此一定不能依賴于線程優(yōu)先級來保證程序的正確操作,這仍然是沒有保障的,要把線程優(yōu)先級用作一種提高程序效率的方法,并且這種方法也不能依賴優(yōu)先級的操作。線程的優(yōu)先級6/26/202315線程控制方法:中斷publicvoidinterrupt()//中斷線程。相當于“喚醒”。如果線程在調(diào)用Object
類的wait()、wait(long)
或wait(long,int)
方法,或者該類的join()、join(long)、join(long,int)、sleep(long)
或sleep(long,int)
方法過程(即“掛起的狀態(tài)”)中受阻,則其中斷狀態(tài)將被清除,它還將收到一個InterruptedException。
publicbooleaninterrupted()//測試當前線程是否已經(jīng)中斷。線程的中斷狀態(tài)由該方法清除。換句話說,如果連續(xù)兩次調(diào)用該方法,則第二次調(diào)用將返回false16如果多個線程同時訪問相同的數(shù)據(jù),那么會造成數(shù)據(jù)不安全(thread-unsafe)。見例子ShareData.java:之前的線程都是獨立的,而且不是同步執(zhí)行。但是,經(jīng)常有些同時運行的線程需要共享數(shù)據(jù),例如:一個線程從文件中讀數(shù)據(jù),另一線程向文件寫數(shù)據(jù),這就需要“同步”。SharingData6/26/202317多線程訪問共享數(shù)據(jù)造成數(shù)據(jù)的破壞的根源在于對數(shù)據(jù)操作的不完整性。而且線程的運行行為依賴與操作系統(tǒng)的線程調(diào)度算法,具有不可預見性。所以前面的例子還會有其它的意外情況。解決的辦法就是線程的同步控制,對于臨界資源的訪問,線程之間必須是同步的。將訪問共享數(shù)據(jù)的代碼修飾為同步代碼,使用synchronized關鍵字。為資源加鎖。注意:synchronized聲明不會被繼承。SharingData46/26/202318synchronized關鍵字將上例中的兩個方法設成synchronized:synchronizedvoidincrease(){x++;y++;}synchronizedvoidtestEquals(){System.out.println(x+”,”+y+”:”+(x==y));}19同步控制6/26/202320wait,notify,notifyAlljava.lang.Objec提供了3個用于線程通用的方法。如果,線程t1和t2共享一個對象s,t1進入一個同步代碼塊(以s為標記的鎖),如果,調(diào)用s.wait(),他將放棄s鎖,進入s的等待池;此時,t2如果獲得了鎖,在代碼中調(diào)用s.notify(),那么t1將被從s等待池中移出,放到s的鎖池中,等待獲得鎖。21調(diào)用某個對象的wait方法的線程必須擁有該對象的鎖,否則會拋出IllegalMonitorStateException。wait方法調(diào)用一定要在同步代碼內(nèi),否則,編譯會通過,但運行失敗。處于對象的waitingpool中的線程可以使用notify喚醒,喚醒后并不能夠立即執(zhí)行,它要重新獲得鎖。JVM不保證某個線程一定會被喚醒??梢允褂胣otifyAll全部喚醒,但降低運行效率,一般不使用。wait,notify,notifyAll6/26/202322Wait與notify的例子有兩個線
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 財務數(shù)據(jù)分析與會計決策支持計劃
- 倉庫工作總結計劃報告
- 年度目標與關鍵績效指標解讀計劃
- 提升業(yè)務能力的規(guī)劃計劃
- 骨科手術效果及并發(fā)癥管理計劃
- 2025年雙鴨山考貨運上崗證試答題
- 2025年佳木斯考貨運資格證考試內(nèi)容
- 2025年安徽貨運從業(yè)模擬考試
- 2025年三明b2貨運資格證模擬考試
- 2025年河池貨運從業(yè)資格證考試題庫答案
- 快手申訴文本
- 重癥患者早期康復的研究進展
- 商鋪租賃合同(有利于承租方)
- 異丁烷脫氫項目可行性研究報告
- 廣東外語外貿(mào)大學會計專碩復試
- 行政處罰案件集體討論審理記錄
- 變電站綜合自動化
- 德語現(xiàn)代主義文學-浙江大學中國大學mooc課后章節(jié)答案期末考試題庫2023年
- 2022年安徽省公務員錄用考試《行測》真題及答案
- 2023年高中音樂課件大宅門-電視劇《大宅門》主題歌
- 國際貿(mào)易地理全套課件
評論
0/150
提交評論