版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
7.1線程的概念
7.2多線程程序設(shè)計(jì)
7.3多線程的狀態(tài)處理
7.4線程的同步與共享7.1線?程?的?概?念線程,有時(shí)被稱為輕量級(jí)進(jìn)程(LightweightProcess,LWP),是程序執(zhí)行流的最小單元。一個(gè)標(biāo)準(zhǔn)的線程由線程ID、當(dāng)前指令指針(PC)、寄存器集合和堆棧組成。另外,線程是進(jìn)程中的一個(gè)實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有運(yùn)行中必需的資源,但它可與同屬一個(gè)進(jìn)程的其他線程共享進(jìn)程所擁有的全部資源。一個(gè)線程可以創(chuàng)建和撤消另一個(gè)線程,同一進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運(yùn)行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運(yùn)行三種基本狀態(tài)。每一個(gè)程序至少有一個(gè)線程,若程序只有一個(gè)線程,那就是程序本身。7.1.1線程、進(jìn)程和多任務(wù)現(xiàn)在的操作系統(tǒng)都是多任務(wù)操作系統(tǒng),每個(gè)運(yùn)行的任務(wù)就是操作系統(tǒng)所做的一件事情,比如在聽歌的同時(shí)還在用MSN和好友聊天。聽歌和聊天就是兩個(gè)任務(wù),這個(gè)兩個(gè)任務(wù)是“同時(shí)”進(jìn)行的。一個(gè)任務(wù)一般對(duì)應(yīng)一個(gè)進(jìn)程,也可能包含好幾個(gè)進(jìn)程。比如運(yùn)行的MSN就對(duì)應(yīng)一個(gè)MSN的進(jìn)程,如果用戶使用的是Windows系統(tǒng),就可以在任務(wù)管理器中看到操作系統(tǒng)正在運(yùn)行的進(jìn)程信息。一般來說,當(dāng)運(yùn)行一個(gè)應(yīng)用程序的時(shí)候,就啟動(dòng)了一個(gè)進(jìn)程,當(dāng)然有些會(huì)啟動(dòng)多個(gè)進(jìn)程。啟動(dòng)進(jìn)程的時(shí)候,操作系統(tǒng)會(huì)為進(jìn)程分配資源,其中最主要的資源是內(nèi)存空間,因?yàn)槌绦蚴窃趦?nèi)存中運(yùn)行的。在進(jìn)程中,有些程序流程塊是可以亂序執(zhí)行的,并且這個(gè)流程塊可以同時(shí)被多次執(zhí)行。實(shí)際上,這樣的流程塊就是線程體。線程是進(jìn)程中亂序執(zhí)行的代碼流程。當(dāng)多個(gè)線程同時(shí)運(yùn)行的時(shí)候,這樣的執(zhí)行模式就成為并發(fā)執(zhí)行。線程與進(jìn)程的比較如下:(1)進(jìn)程:每個(gè)進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)程上下文),進(jìn)程切換的開銷大。(2)線程:即輕量的進(jìn)程,同一類線程共享代碼和數(shù)據(jù)空間。每個(gè)線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(PC),線程切換的開銷小。(3)多進(jìn)程:在操作系統(tǒng)中能同時(shí)運(yùn)行多個(gè)任務(wù)程序。(4)多線程:在同一應(yīng)用程序中有多個(gè)順序流同時(shí)執(zhí)行。7.1.2Java中的多線程多線程機(jī)制是Java語言的又一重要特征,使用多線程技術(shù)可以使系統(tǒng)同時(shí)運(yùn)行多個(gè)執(zhí)行體,這樣可以加快程序的響應(yīng)時(shí)間,提高計(jì)算機(jī)資源的利用率。使用多線程技術(shù)可以提高整個(gè)應(yīng)用系統(tǒng)的性能。在Java中,創(chuàng)建線程有兩種方法:一種是通過創(chuàng)建Thread類的子類來實(shí)現(xiàn);另一種是通過實(shí)現(xiàn)Runnable接口的類來實(shí)現(xiàn)。7.2多線程程序設(shè)計(jì)7.2.1從Thread類繼承從Thread類繼承是創(chuàng)建一個(gè)線程較為簡便的方法。在繼承這個(gè)類之后,我們需要覆蓋它的run方法,每一個(gè)線程都會(huì)分別執(zhí)行一次run方法。下面程序是一個(gè)多線程的實(shí)例。在這個(gè)程序中有兩個(gè)線程,每個(gè)線程都會(huì)執(zhí)行一次run方法,但是兩個(gè)線程執(zhí)行的順序并不固定,因此,輸出誰先誰后都是隨機(jī)的。程序后面是某一次運(yùn)行的輸出(注意每次運(yùn)行都會(huì)不同)。注意,創(chuàng)建線程后,start方法用于啟動(dòng)線程。在一個(gè)方法中調(diào)用Thread.currentThread().getName()方法,可以獲取當(dāng)前線程的名字。在mian方法中調(diào)用該方法,獲取的是主線程的名字。多線程程序是亂序執(zhí)行。因此,只有亂序執(zhí)行的代碼才有必要設(shè)計(jì)為多線程。Thread.sleep()方法的調(diào)用目的是不讓當(dāng)前線程獨(dú)自占有該進(jìn)程所獲取的CPU資源,以留出一定時(shí)間給其他線程執(zhí)行的機(jī)會(huì)。實(shí)際上所有的多線程代碼執(zhí)行順序都是不確定的,每次執(zhí)行的結(jié)果都是隨機(jī)的。7.2.2實(shí)現(xiàn)Runnable接口【示例7.2】通過接口構(gòu)造線程體。publicclassClockextendsjava.applet.AppletimplementsRunnable{ //實(shí)現(xiàn)接口ThreadclockThread;publicvoidstart(){//該方法是Applet的方法不是線程的方法if(clockThread==null){clockThread=newThread(this,"Clock");/*線程體是Clock對(duì)象本身線程名字為"Clock"*/clockThread.start(); //啟動(dòng)線程}}
publicvoidrun(){ //run()方法中是線程執(zhí)行的內(nèi)容while(clockThread!=null){repaint(); //刷新顯示畫面try{clockThread.sleep(1000);//睡眠1秒即每隔1秒執(zhí)行一次}catch(InterruptedExceptione){}}}publicvoidpaint(Graphicsg){Datenow=newDate();//獲得當(dāng)前的時(shí)間對(duì)象g.drawString(now.getHours()+":"+now.getMinutes()+":"+now.getSeconds(),5,10);//顯示當(dāng)前時(shí)間}publicvoidstop(){//該方法是Applet的方法不是線程的方法clockThread.stop();clockThread=null;}}以上示例是通過每隔1秒就執(zhí)行線程的刷新畫面功能來顯示當(dāng)前的時(shí)間;看起來的效果就是一個(gè)時(shí)鐘每隔1秒就變化一次。由于采用的是實(shí)現(xiàn)接口Runnable的方式,所以該類Clock還繼承了Applet,Clock就可以Applet的方式運(yùn)行。構(gòu)造線程體的兩種方法的比較如下:(1)使用Runnable接口。①可以將CPU代碼和數(shù)據(jù)分開,從而形成清晰的模型。②可以從其他類繼承。③保持程序風(fēng)格的一致性。(2)直接繼承Thread類。①不能從其他類繼承。②編寫簡單,可以直接操作線程無需使用Thread.currentThread()。7.3多線程的狀態(tài)處理7.3.1線程的狀態(tài)線程的狀態(tài)可分為就緒、運(yùn)行、阻塞、死亡等。就緒:當(dāng)線程創(chuàng)建之后,調(diào)用start方法,自動(dòng)運(yùn)行run方法。此時(shí),線程獲得了系統(tǒng)資源,并處于等待CPU的狀態(tài)。運(yùn)行:線程獲得了CPU資源。阻塞:處于運(yùn)行狀態(tài)的線程因?yàn)槿鄙倌撤N資源而不得不停止運(yùn)行,進(jìn)入阻塞狀態(tài)。死亡:線程的run方法運(yùn)行結(jié)束時(shí),線程進(jìn)入死亡狀態(tài)。7.3.2對(duì)線程狀態(tài)的控制1.終止線程線程終止后其生命周期也就結(jié)束了,即進(jìn)入死亡狀態(tài),終止后的線程不能再被調(diào)度執(zhí)行。以下是進(jìn)入死亡狀態(tài)的幾種情況線程:(1)線程執(zhí)行完其run()方法后會(huì)自然終止。(2)通過調(diào)用線程的實(shí)例方法stop()來終止線程。2.測(cè)試線程狀態(tài)可以通過Thread中的isAlive()方法來獲取線程是否處于活動(dòng)狀態(tài)。3.線程的暫停和恢復(fù)有幾種方法可以暫停一個(gè)線程的執(zhí)行,并在適當(dāng)?shù)臅r(shí)候再恢復(fù)其執(zhí)行。(1)?sleep()方法。當(dāng)前線程睡眠(停止執(zhí)行),即若干毫秒線程由運(yùn)行中狀態(tài),進(jìn)入不可運(yùn)行狀態(tài),停止執(zhí)行時(shí)間到后線程進(jìn)入可運(yùn)行狀態(tài)。(2)?suspend()和resume()方法。線程的暫停和恢復(fù)通過調(diào)用線程的suspend()方法使線程暫時(shí)由可運(yùn)行態(tài)切換到不可運(yùn)行態(tài),若此線程想再回到可運(yùn)行態(tài),必須由其他線程調(diào)用resume()方法來實(shí)現(xiàn)。注:從JDK1.2開始就不再使用suspend()和resume()。(3)?join()方法。當(dāng)前線程等待調(diào)用該方法的線程結(jié)束后,再恢復(fù)執(zhí)行。7.4線程的同步與共享因?yàn)槎嗑€程提供了程序的異步執(zhí)行的功能,可能會(huì)出現(xiàn)兩個(gè)或多個(gè)線程同時(shí)訪問共享資源,所以在必要時(shí)還必須提供一種同步機(jī)制。線程同步可以確保當(dāng)兩個(gè)或多個(gè)線程需要訪問共享資源時(shí),一次只有一個(gè)線程使用資源。7.4.1線程的同步1.線程的同步機(jī)制在Java中,使用synchronized關(guān)鍵字修飾的方法稱為同步方法。當(dāng)某一線程在一個(gè)同步方法中執(zhí)行的時(shí)候,其他所有企圖調(diào)用同步方法的線程或者其他方法都必須等待。在Java中使用synchronized的兩種方式如下:(1)放在方法前面,這樣調(diào)用該方法的線程均將獲得對(duì)象的鎖。(2)放在代碼塊前面,它也有以下兩種形式:synchronized(this){…}:代碼塊中的代碼將獲得當(dāng)前對(duì)象引用的鎖。synchronized(otherObj){…}:代碼塊中的代碼將獲得指定對(duì)象引用的鎖。2.死鎖線程系統(tǒng)還存在一個(gè)更大的風(fēng)險(xiǎn),即“死鎖”。死鎖是保護(hù)數(shù)據(jù)不受線程損壞的自然結(jié)果。如果共享資源有狀態(tài),而且在多個(gè)線程處于活動(dòng)狀態(tài)時(shí)更改代碼塊的狀態(tài),則當(dāng)多個(gè)線程運(yùn)行時(shí),就可能會(huì)潛在地破壞資源狀態(tài)。線程是獨(dú)立調(diào)度的,不一定按固定順序運(yùn)行,這必然存在風(fēng)險(xiǎn)。要解決這個(gè)問題,應(yīng)將數(shù)據(jù)設(shè)置為私有,并同步代碼塊。但是,如果在應(yīng)用程序中定義同步代碼,則可能出現(xiàn)死鎖。具體地講,對(duì)于兩個(gè)已經(jīng)有鎖標(biāo)記的線程而言,如果它們都試圖調(diào)用受另一個(gè)線程的鎖標(biāo)記保護(hù)的同步代碼,則可能出現(xiàn)死鎖。在出現(xiàn)死鎖時(shí),兩個(gè)線程將永不能再運(yùn)行。另外,調(diào)用使用相同鎖標(biāo)記的方法的其他線程也將出現(xiàn)死鎖。當(dāng)以下四個(gè)條件同時(shí)滿足時(shí),就會(huì)發(fā)生死鎖:(1)互斥條件。線程使用的資源中至少有一個(gè)是不能共享的。(2)至少有一個(gè)進(jìn)程必須有一個(gè)資源且正在等待獲取一個(gè)當(dāng)前被別的進(jìn)程持有的資源。(3)資源不能被進(jìn)程搶占。所有的進(jìn)程必須把資源釋放當(dāng)作普通事件。(4)必須有循環(huán)等待。一個(gè)進(jìn)程等待其他進(jìn)程所持有的資源,這時(shí),后者又在等待另一個(gè)進(jìn)程所持有的資源,這樣直到有一個(gè)進(jìn)程在等待第一個(gè)進(jìn)程所持有的資源,使大家都被鎖住。所以,要防止死鎖發(fā)生,只需破壞其中一個(gè)條件即可
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度肉類食品品牌推廣與營銷合同
- 二零二五年度法院執(zhí)行離婚協(xié)議書及婚后財(cái)產(chǎn)分割與子女監(jiān)護(hù)權(quán)協(xié)議
- 二零二五年度網(wǎng)絡(luò)安全防護(hù)與應(yīng)急響應(yīng)草擬合同
- 南京科技職業(yè)學(xué)院《傳染病學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 南京航空航天大學(xué)金城學(xué)院《建筑空間構(gòu)成》2023-2024學(xué)年第一學(xué)期期末試卷
- 南方醫(yī)科大學(xué)《小學(xué)道德與法治教學(xué)專題研究》2023-2024學(xué)年第一學(xué)期期末試卷
- 牡丹江大學(xué)《羽毛球》2023-2024學(xué)年第一學(xué)期期末試卷
- 民辦合肥財(cái)經(jīng)職業(yè)學(xué)院《風(fēng)景資源保護(hù)與規(guī)劃》2023-2024學(xué)年第一學(xué)期期末試卷
- 綿陽飛行職業(yè)學(xué)院《外國文學(xué)(3)》2023-2024學(xué)年第一學(xué)期期末試卷
- 馬鞍山職業(yè)技術(shù)學(xué)院《中國藝術(shù)史》2023-2024學(xué)年第一學(xué)期期末試卷
- DISC性格與能力測(cè)試題及答案解析
- 年產(chǎn)12萬噸裝配式智能鋼結(jié)構(gòu)項(xiàng)目可行性研究報(bào)告模板-立項(xiàng)備案
- TB 10106-2023鐵路工程地基處理技術(shù)規(guī)程
- 三年級(jí)下冊(cè)綜合實(shí)踐活動(dòng)教學(xué)設(shè)計(jì)- 嶺南水果|粵教版 52張
- 滬教版數(shù)學(xué)六年級(jí)(上)第二章分?jǐn)?shù)課課練和單元練習(xí)卷及參考答案
- 承包意向書2024年
- 小學(xué)心理健康教師資格考試面試2024年下半年試題與參考答案
- (正式版)QC∕T 1206.2-2024 電動(dòng)汽車動(dòng)力蓄電池?zé)峁芾硐到y(tǒng) 第2部分:液冷系統(tǒng)
- (正式版)CB∕T 4550-2024 船舶行業(yè)企業(yè)安全設(shè)備設(shè)施管理規(guī)定
- 完整版肺癌護(hù)理查房課件
- 正規(guī)光伏屋頂租賃合同
評(píng)論
0/150
提交評(píng)論