版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Java線程Javathread第十二章目標(biāo)/OBJECTIVE0102030405了解線程的概念、特點以及線程的操作方法熟悉線程的生命周期和調(diào)度機(jī)制優(yōu)先級了解線程狀態(tài)轉(zhuǎn)換了解線程同步原理,掌握線程同步的方法掌握實現(xiàn)線程交互的方法01線程和多線程12.1線程和多線程1.線程的概念線程是操作系統(tǒng)能夠進(jìn)行運算調(diào)度的最小單位,它被包含在進(jìn)程中,是進(jìn)程中的實際運作單位。一條線程指的是進(jìn)程中一個單一順序的控制流,一個進(jìn)程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務(wù)。在UnixSystemV及SunOS中也被稱為輕量進(jìn)程(lightweightprocesses),但輕量進(jìn)程更多指內(nèi)核線程(kernelthread),而把用戶線程(userthread)稱為線程。為了實現(xiàn)多線程的效果,Java語言把線程或執(zhí)行環(huán)境當(dāng)作一個封裝對象,包含CPU及自己的程序代碼和數(shù)據(jù),由虛擬機(jī)提供控制。Java類庫中的類java.lang.Thread允許創(chuàng)建這樣的線程,并可控制所創(chuàng)建的線程。12.1線程和多線程2.線程的特點及結(jié)構(gòu)(1)線程的特點·線程是輕型實體,只有一點必不可少的資源,即程序、數(shù)據(jù)和TCB(ThreadControlBlock)?!ぞ€程是是獨立調(diào)度和分派的基本單位,在多核或多CPU的系統(tǒng)上可以提高程序的執(zhí)行效率?!ぞ€程可以共享進(jìn)程資源,如地址空間、文件描述符和信號處理等?!ぞ€程之間可以通過共享內(nèi)存或消息傳遞進(jìn)行通信,但需要使用同步機(jī)制來保證數(shù)據(jù)的一致性。12.1線程和多線程(2)線程的結(jié)構(gòu)·虛擬CPU,封裝在java.lang.Thread類中,控制著整個線程的運行?!?zhí)行的代碼,傳遞給Thread類,由Thread類控制順序執(zhí)行。·處理的數(shù)據(jù),傳遞給Thread類,是代碼執(zhí)行過程中所要處理的數(shù)據(jù)。02線程的狀態(tài)12.2線程的狀態(tài)Java的線程是通過Java的軟件包java.lang中定義的類Thread來實現(xiàn)的,生成一個Thread類的對象后,就生成了一個線程,可以通過操作該對象實現(xiàn)啟動線程、終止線程、掛起線程等操作。1.線程的生命周期線程是一個動態(tài)執(zhí)行的過程,它也有一個從產(chǎn)生到死亡的過程。12.2線程的狀態(tài)2.線程的狀態(tài)分類線程的狀態(tài)是指線程在執(zhí)行過程中的不同階段。線程的狀態(tài)可以分為以下幾種:1.新建狀態(tài)(New):線程對象被創(chuàng)建后,就進(jìn)入了新建狀態(tài)。2.就緒狀態(tài)(Runnable):也被稱為“可執(zhí)行狀態(tài)”。線程對象被創(chuàng)建后,調(diào)用該對象的start()方法,從而啟動該線程。3.運行狀態(tài)(Running):線程獲取CPU權(quán)限進(jìn)行執(zhí)行。需要注意的是,線程只能從就緒狀態(tài)進(jìn)入到運行狀態(tài)。4.阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因為某種原因放棄CPU使用權(quán),暫時停止運行。直到線程進(jìn)入就緒狀態(tài),才有機(jī)會轉(zhuǎn)到運行狀態(tài)。5.死亡狀態(tài)(Dead):線程執(zhí)行完畢或者因異常退出了run()方法,該線程結(jié)束生命周期。12.2線程的狀態(tài)在程序中常常調(diào)用interrupt()來終止線程。interrupt()不僅可以中斷正在運行的線程,也可以中斷處于阻塞狀態(tài)的線程。當(dāng)interrupt()中斷處于阻塞狀態(tài)的線程時,系統(tǒng)會出現(xiàn)InterruptException異常。03創(chuàng)建線程12.3創(chuàng)建線程1.通過繼承Thread類法創(chuàng)建線程Thread類中定義了許多可以完成線程處理工作的方法,因此可以通過定義一個Thread的子類來創(chuàng)建一個新的線程。繼承得到的類必須重寫run()方法,該方法是新線程的入口點。通過繼承Thread類創(chuàng)建一個新線程包含一下幾個步驟:1.定義一個Thread類的子類。2.用該子類創(chuàng)建一個對象。3.使用start()方法啟動線程。12.3創(chuàng)建線程2.通過實現(xiàn)Runnable接口創(chuàng)建線程Runnable是Java中專門用來實現(xiàn)線程的接口,其中只定義了一個run()方法。因此,創(chuàng)建一個線程,最簡單的方法是創(chuàng)建一個實現(xiàn)Runnable接口的類。通過實現(xiàn)Runnable接口創(chuàng)建線程具體步驟如下:1.創(chuàng)建一個類并實現(xiàn)Runnable接口。這個接口只有一個方法run(),需要在其中定義線程的邏輯。2.在類中實現(xiàn)run()方法,編寫線程的邏輯代碼。3.在主程序中創(chuàng)建一個Runnable對象的實例。12.3創(chuàng)建線程4.創(chuàng)建一個Thread對象,將Runnable對象作為參數(shù)傳遞給Thread的構(gòu)造函數(shù)。5.調(diào)用Thread對象的start()方法,啟動線程。12.3創(chuàng)建線程例12.1使用Runnable接口創(chuàng)建兩個線程,并讓兩個線程同時打印自己的名字。Copilot指令:使用Runnable接口創(chuàng)建兩個線程,并讓兩個線程同時打印自己的名字。12.3創(chuàng)建線程12.3創(chuàng)建線程3.通過Callable和Future創(chuàng)建線程Callable和Future是Java提供的一種異步編程的方式,可以在一個新的線程中執(zhí)行一個有返回值的任務(wù),并且可以獲取任務(wù)的執(zhí)行結(jié)果。通過Callable和Future創(chuàng)建線程的步驟如下:1.創(chuàng)建一個實現(xiàn)了Callable接口的類,并重寫call方法,該方法是線程的執(zhí)行體,并且有返回值3。2.創(chuàng)建一個FutureTask對象,用來包裝Callable對象,該對象可以獲取Callable對象的call方法的返回值45。3.創(chuàng)建一個線程池對象,用來管理線程的執(zhí)行。4.將FutureTask對象作為參數(shù),提交給線程池對象,創(chuàng)建一個新的線程。5.調(diào)用FutureTask對象的get方法,來獲取子線程執(zhí)行結(jié)束后的返回值。12.3創(chuàng)建線程Copilot指令:使用Callable和Future創(chuàng)建一個計算平方根的線程,計算并輸出2的平方根。例12.2使用Callable和Future創(chuàng)建一個計算平方根的線程,計算并輸出2的平方根。12.3創(chuàng)建線程12.3創(chuàng)建線程4.不同創(chuàng)建線程的方法的區(qū)別1.采用實現(xiàn)Runnable、Callable接口的方式創(chuàng)建多線程時,線程類只是實現(xiàn)了Runnable接口或Callable接口,還可以繼承其他類。2.使用繼承Thread類的方式創(chuàng)建多線程時,編寫簡單,如果需要訪問當(dāng)前線程,則無需使用Thread.currentThread()方法,直接使用this即可獲得當(dāng)前線程。04線程的優(yōu)先級12.4線程的優(yōu)先級1.線程的不同優(yōu)先級
在筆記時,人們通常會用不同顏色標(biāo)記一些重要內(nèi)容,也就是所謂的“劃重點”,不同的顏色代表了內(nèi)容的重要程度,這有助于快速查找、記憶筆記中的重要內(nèi)容。Java中的線程與之相似,每一個Java線程都有一個優(yōu)先級,線程越重要優(yōu)先級越高,這有助于CPU對線程的調(diào)度。
處于就緒狀態(tài)的線程需要獲得CPU的執(zhí)行權(quán)才可以開始運行,當(dāng)CPU需要執(zhí)行一個多線程人物時,就需要根據(jù)不同進(jìn)程的狀態(tài)及優(yōu)先級來進(jìn)行調(diào)度。
Java線程的優(yōu)先級為整數(shù)且有三個不同的取值。
1.MIN_PRIORITY:值為1
2.NORM_PRIORITY:值為53.MAX_PRIORITY:值為10
線程的默認(rèn)優(yōu)先級為NORM_PRIORITY(5)。12.4線程的優(yōu)先級2.線程的調(diào)度方法Java中的線程調(diào)度由線程調(diào)度器完成,線程調(diào)度方法通常是搶占式的,擁有執(zhí)行權(quán)的可執(zhí)行線程會持續(xù)執(zhí)行。當(dāng)線程執(zhí)行完畢或被阻塞時,等待執(zhí)行的隊列中的線程會獲得執(zhí)行權(quán)并開始執(zhí)行。Java的線程調(diào)度方法如下:1.按優(yōu)先級進(jìn)行排序,優(yōu)先級高的線程優(yōu)先執(zhí)行。2.線程被創(chuàng)建時會默認(rèn)賦予與其父類相同的優(yōu)先級,若無父類,則賦予其默認(rèn)優(yōu)先級NORM_PRIORITY(5)。3.優(yōu)先級相同的線程按照”先進(jìn)先出“的原則執(zhí)行。Java中有多種有關(guān)線程優(yōu)先級的方法。例如
Thread類的setPriority(int)方法可以直接設(shè)置線程的優(yōu)先級。ThreadMXBean類的getThreadPriority(long)方法可以查詢和設(shè)置線程的優(yōu)先級。05線程的基本控制12.5線程的基本控制1.暫停與喚醒線程運行中的線程可以通過一些方法暫停,暫停線程也稱為掛起。線程被暫停后必須通過一定的方法將其喚醒。被暫停后,線程就失去了執(zhí)行權(quán),若等待執(zhí)行的隊列中有其他線程則執(zhí)行權(quán)會交給該線程,若無其他可運行的線程則會等待線程被喚醒后繼續(xù)執(zhí)行。以下是幾種暫停線程的方法:1.sleep():該方法直接暫停該線程的執(zhí)行,讓線程“睡一會兒”,線程進(jìn)入阻塞狀態(tài)。2.yield():該方法使當(dāng)前正在執(zhí)行的線程暫停一次,允許其他線程執(zhí)行,不阻塞,線程進(jìn)入就緒狀態(tài),如果沒有其他等待執(zhí)行的線程,這個時候當(dāng)前線程就會馬上恢復(fù)執(zhí)行。3.join():調(diào)用該方法的線程強(qiáng)制執(zhí)行,進(jìn)入運行狀態(tài)。其他正在運行的線程進(jìn)入阻塞狀態(tài),該線程執(zhí)行完畢后,其他線程繼續(xù)執(zhí)行。喚醒線程的方法為notify()/notifyAll(),notify()方法用于喚醒在對象上等待的一個線程。并使它進(jìn)入就緒狀態(tài);notifyAll()方法用于喚醒在對象上等待的所有線程。它會將等待隊列中的所有線程都喚醒,并使它們進(jìn)入就緒狀態(tài)。12.5線程的基本控制2.結(jié)束線程結(jié)束線程有兩種情況,一種為線程執(zhí)行完畢自動結(jié)束,另一種為調(diào)用結(jié)束線程的方法來結(jié)束線程。例如從網(wǎng)絡(luò)下載一個100M的文件,如果網(wǎng)速很慢,用戶等得不耐煩,就可能在下載過程中點“取消”,這時,程序就需要中斷下載線程的執(zhí)行。通常調(diào)用interrupt()方法來結(jié)束線程。12.5線程的基本控制3.檢查線程在不清楚一個線程的狀態(tài)時,可以通過下列集中方法檢查線程:1.isAlive()方法:isAlive()方法用于檢查線程是否處于活動狀態(tài)。如果線程已啟動且尚未終止,則返回true;否則返回false。2.getState()方法:getState()方法用于獲取線程的狀態(tài)。它返回一個Thread.State枚舉表示線程的狀態(tài),如NEW(新建)、RUNNABLE(可運行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(計時等待)和TERMINATED(終止)。3.isInterrupted()方法:isInterrupted()方法用于檢查線程的中斷狀態(tài)。如果線程的中斷狀態(tài)為true,則返回true;否則返回false。注意,調(diào)用isInterrupted()方法不會清除線程的中斷狀態(tài)。4.interrupted()方法:interrupted()方法用于檢查當(dāng)前線程的中斷狀態(tài),并清除中斷狀態(tài)。如果當(dāng)前線程的中斷狀態(tài)為true,則返回true;否則返回false。06線程的同步問題12.6線程的同步問題1.線程間的資源互斥當(dāng)多個線程同時運行時,線程的調(diào)度由操作系統(tǒng)決定,程序本身無法決定。因此,任何一個線程都有可能在任何指令處被操作系統(tǒng)暫停,然后在某個時間段后繼續(xù)執(zhí)行。所以當(dāng)同時運行的多個線程需要用到同一個變量或同一段代碼時,運行的結(jié)果就可能由于每個線程的執(zhí)行狀況不同而產(chǎn)生誤差,即產(chǎn)生了資源互斥。為避免產(chǎn)生資源互斥現(xiàn)象,需要用到線程同步的方法。12.6線程的同步問題2.線程同步方法當(dāng)線程間發(fā)生資源互斥的情況時,為了避免這種情況產(chǎn)生的影響,可以采取一些手段限制多個線程對同一個資源的使用。例如某部門迎新晚會前,各節(jié)目組均需要占用舞臺進(jìn)行彩排,規(guī)定舞臺在同一時間內(nèi)只能由一個節(jié)目組使用,這樣即可讓每個節(jié)目組都能順利使用舞臺并避免多個節(jié)目組同時占用舞臺互相影響。相似地,在使用多線程編程時,可以通過給一個共享資源“上鎖”,使其只能同時由一個線程使用來避免資源互斥現(xiàn)象,因此引入“對象互斥鎖”概念。12.6線程的同步問題“對象互斥鎖”阻止多個線程同時訪問同一資源,每個對象的實例均可以有一個“對象互斥鎖”。有多種方式實現(xiàn)“對象互斥鎖”:1.使用關(guān)鍵字volatile聲明變量。2.使用關(guān)鍵字synchronized聲明方法或一段代碼。一般情況下,經(jīng)常使用關(guān)鍵字synchronized聲明一個方法,該方法對多個線程需同時用到的變量進(jìn)行了操作。07死鎖12.7死鎖當(dāng)線程試圖連續(xù)獲取多個鎖時,就可能發(fā)生死鎖的情況,死鎖產(chǎn)生的具體條件為:1.互斥使用,即當(dāng)資源被一個線程使用(占有)時,別的線程不能使用2.不可搶占,資源請求者不能強(qiáng)制從資源占有者手中奪取資源,資源只能由資源占有者主動釋放。3.請求和保持,即當(dāng)資源請求者在請求其他的資源的同時保持對原有資源的占有。4.循環(huán)等待,即存在一個等待隊列:P1占有P2的資源,P2占有P3的資源,P3占有P1的資源。這樣就形成了一個等待環(huán)路。當(dāng)上述四個條件都成立的時候,便形成死鎖。例如:一個程序中設(shè)計了兩個線程,線程1和線程2,需要用到兩個鎖,鎖1和鎖2,兩個線程同步執(zhí)行時,線程1與線程2同步運行,線程1獲得了鎖1,線程2獲得了鎖2,之后線程1試圖獲取鎖2,線程2試圖獲取鎖1,兩個線程進(jìn)入無盡的等待,這就發(fā)生了死鎖。08線程的交互12.8線程的交互在多線程編程中,多條線程并非都是毫無關(guān)聯(lián)的,線程之間存在一些關(guān)聯(lián),需要一種通信手段實現(xiàn)交互才能順利完成工作。一個典型的例子是生產(chǎn)者-消費者問題,生產(chǎn)者和消費者在同一時間段內(nèi)共用同一個存儲空間,生產(chǎn)者向空間里存放數(shù)據(jù),而消費者取用數(shù)據(jù),如果不加以協(xié)調(diào)可能會出現(xiàn)以下情況:存儲空間已滿,而生產(chǎn)者占用著它,消費者等著生產(chǎn)者讓出空間從而取出產(chǎn)品,生產(chǎn)者等著消費者消費產(chǎn)品,從而向空間中添加產(chǎn)品。互相等待,從而發(fā)生死鎖。為解決上述問題,就需要兩者進(jìn)行交互。12.8線程的交互實現(xiàn)線程的交互需要使用wait(),notify()/notifyAll()的同步機(jī)制,wait()使線程釋放持有的“對象互斥鎖”使線程可以獲取這個鎖,在儲存空間沒有可取出的新數(shù)據(jù)時,就需要使消費者退出儲存空間,使生產(chǎn)者可以使用。該方法使thread線程釋放持有的“對象鎖”。相應(yīng)地,生產(chǎn)者需要在放入產(chǎn)品后提醒消費者,使生產(chǎn)者退出儲存空間后,消費者可以進(jìn)入并取出數(shù)據(jù)。notify()/notifyAll使線程被喚醒,進(jìn)入等待獲取“對象鎖”的隊列中。12.8線程的交互例12.3使用wait()和notify()/notifyAll()同步機(jī)制,模擬生產(chǎn)者和消費者的問題。生產(chǎn)者線程負(fù)責(zé)生產(chǎn)物品,消費者線程負(fù)責(zé)消費物品。Copilot指令:使用wait()和notify()/notifyAll()同步機(jī)制,模擬生產(chǎn)者和消費者的問題。生產(chǎn)者線程負(fù)責(zé)生產(chǎn)物品,消費者線程負(fù)責(zé)消費物品。12.8線程的交互12.8線程的交互12.8
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年紹興市上虞區(qū)中醫(yī)醫(yī)院醫(yī)共體招聘編外人員5人模擬筆試試題及答案解析
- 2025年福建泉州惠安縣宏福殯儀服務(wù)有限公司招聘5人參考考試試題及答案解析
- 2025年杭州市上城區(qū)閘弄口街道社區(qū)衛(wèi)生服務(wù)中心招聘編外1人考試參考試題及答案解析
- 深度解析(2026)GBT 26103.5-2010NGCLZ型帶制動輪鼓形齒式聯(lián)軸器
- 2025浙江寧波市象山半邊山紫冠投資有限公司酒店管理分公司(寧波象山海景皇冠假日酒店)招聘3人參考考試題庫及答案解析
- 深度解析(2026)《GBT 25982-2024客車車內(nèi)噪聲限值及測量方法》(2026年)深度解析
- 2025四川德陽市旌陽區(qū)孝泉鎮(zhèn)衛(wèi)生院(旌陽區(qū)第二人民醫(yī)院)招聘2人備考筆試題庫及答案解析
- 深度解析(2026)《GBT 25796-2010反應(yīng)艷黃W-2G(C.I.反應(yīng)黃39)》
- 深度解析(2026)《GBT 25734-2010牦牛肉干》(2026年)深度解析
- 深度解析(2026)《GBT 25688.2-2010土方機(jī)械 維修工具 第2部分:機(jī)械式拉拔器和推拔器》
- 2025至2030中國聚四氟乙烯(PTFE)行業(yè)經(jīng)營狀況及投融資動態(tài)研究報告
- 教育、科技、人才一體化發(fā)展
- 營銷與客戶關(guān)系管理-深度研究
- 耐壓試驗操作人員崗位職責(zé)
- 2020-2021學(xué)年廣東省廣州市黃埔區(qū)二年級(上)期末數(shù)學(xué)試卷
- 財政部政府采購法律法規(guī)與政策學(xué)習(xí)知識考試題庫(附答案)
- 長鑫存儲在線測評題
- DL∕T 5344-2018 電力光纖通信工程驗收規(guī)范
- T-CCIIA 0004-2024 精細(xì)化工產(chǎn)品分類
- 世界當(dāng)代史教材
- 高壓電動機(jī)保護(hù)原理及配置
評論
0/150
提交評論