![Java程序設計PPT課件版 第八章 多線程_第1頁](http://file4.renrendoc.com/view/227673d753d601f74285b64893b47c3d/227673d753d601f74285b64893b47c3d1.gif)
![Java程序設計PPT課件版 第八章 多線程_第2頁](http://file4.renrendoc.com/view/227673d753d601f74285b64893b47c3d/227673d753d601f74285b64893b47c3d2.gif)
![Java程序設計PPT課件版 第八章 多線程_第3頁](http://file4.renrendoc.com/view/227673d753d601f74285b64893b47c3d/227673d753d601f74285b64893b47c3d3.gif)
![Java程序設計PPT課件版 第八章 多線程_第4頁](http://file4.renrendoc.com/view/227673d753d601f74285b64893b47c3d/227673d753d601f74285b64893b47c3d4.gif)
![Java程序設計PPT課件版 第八章 多線程_第5頁](http://file4.renrendoc.com/view/227673d753d601f74285b64893b47c3d/227673d753d601f74285b64893b47c3d5.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第六章多線程授課教師:高成珍QQ:1281147324進程和線程綜合示例線程的互斥和同步線程的狀態(tài)和生命周期創(chuàng)建線程的兩種方式本章主要內(nèi)容能夠自主實現(xiàn)多線程示例理解線程的互斥和同步熟練掌握創(chuàng)建線程的兩種方式
熟練掌握線程狀態(tài)間的轉化
本章重點與難點理解和掌握進程和線程的概念進程和線程幾乎所有的操作系統(tǒng)都支持同時運行多個任務,一個任務通常就是一個程序,每個運行中的程序就是一個進程(Process)。當一個程序運行時,內(nèi)部可能包含了多個順序執(zhí)行流,每個順序執(zhí)行流就是一個線程(Thread)。進程與線程的區(qū)別1、進程擁有自己獨立的資源,線程不擁有資源,它與父進程的其他線程共享該進程所擁有的全部資源;2、創(chuàng)建或撤銷一個進程所需要的開銷比創(chuàng)建或撤銷一個線程所需要的開銷大;3、進程為重量級組件,線程為輕量級組件;任務1任務2任務3多線程在多個CPU上運行多線程分享單個CPU任務1任務2任務3并行和并發(fā)
并行(Parallel)指在同一時刻,有多條指令在多個處理器上同時執(zhí)行;
并發(fā)(concurrency)指在同一時刻只能有一條指令執(zhí)行,但多個進程指令被快速輪換執(zhí)行,使得宏觀上具有多個進程同時執(zhí)行的效果。線程類介紹(Thread)
publicstaticThreadcurrentThread():返回當前執(zhí)行的線程對象;publicfinalStringgetName():返回該線程的名稱;publicfinalvoidsetPriority(int
newPriority):更改線程的優(yōu)先級。publicThread.State
getState():返回該線程的狀態(tài)。publicvoidstart():使該線程開始執(zhí)行,多次啟動一個線程是非法的;publicstaticvoidsleep(long
millis)throwsInterruptedException在指定的毫秒數(shù)內(nèi)讓當前正在執(zhí)行的線程休眠(暫停執(zhí)行)。publicstaticvoidyield():暫停當前正在執(zhí)行的線程對象,并執(zhí)行其他線程。構造方法:Thread()、Thread(Stringname)、Thread(Runnabletarget)線程的創(chuàng)建和啟動定義Thread類的子類,并重寫該類的run()方法,該run()方法的方法體就代表了線程需要完成的任務;創(chuàng)建Thread子類的實例,即創(chuàng)建線程對象;調(diào)用線程對象的start()方法啟動該線程。1、繼承Thread類創(chuàng)建線程類
在Java中,程序入口被自動創(chuàng)建為主線程,main()方法的方法體就是主線程的線程執(zhí)行體。
啟動線程使用start()方法,而不是run()方法!如果直接調(diào)用run()方法,系統(tǒng)會把線程對象當成一個普通對象,而run()方法也是一個普通方法,而不是線程執(zhí)行體。線程的創(chuàng)建和啟動定義Runnable接口的實現(xiàn)類,并重寫該接口的run()方法,該run()方法的方法體即該線程的線程執(zhí)行體;創(chuàng)建Runnable實現(xiàn)類的實例,并以此實例作為Thread的target來創(chuàng)建Thread對象,該Thread對象才是真正的線程對象;調(diào)用線程對象的start()方法啟動該線程。2、實現(xiàn)Runnable接口創(chuàng)建線程第一種方式只能在類沒有繼承其它任何類的情況下才能使用?,如果一個類要繼承其它的類,最好選用第二種方法,這樣有更好的靈活性。線程的生命周期1、新建和就緒狀態(tài)當程序使用new關鍵字創(chuàng)建一個線程之后,該線程就處于新建狀態(tài),此時它和其他的Java對象一樣,僅僅由Java虛擬機為其分配內(nèi)存,并初始化其成員變量的值。當調(diào)用線程對象的start()方法之后,該線程就處于就緒狀態(tài),處于這個狀態(tài)中的線程并沒有開始運行,只是表示該線程可以運行了。至于該線程何時開始運行,取決于JVM里線程調(diào)度器的調(diào)度。在線程的生命周期中,要經(jīng)過新建(New)、就緒(Runnable)、運行(Running)、阻塞(Blocked)和死亡(Dead)5種狀態(tài)。線程啟動以后,不可能一直霸占著CPU獨自運行,CPU需要在多條線程之間切換,于是線程狀態(tài)也會多次在運行、阻塞之間切換。線程的生命周期2、運行和阻塞狀態(tài)如果處于就緒狀態(tài)的線程獲得了CPU,開始執(zhí)行run()方法,則該線程處于運行狀態(tài),線程在運行過程中會被中斷,目的是使其他線程獲得執(zhí)行的機會,線程調(diào)度的細節(jié)取決于底層平臺所采用的策略。當發(fā)生如下情況時,線程會進入阻塞狀態(tài)線程調(diào)用sleep()方法主動放棄所占用的處理器資源;線程調(diào)用一個阻塞式IO方法,在該方法返回之前,該線程被阻塞;線程試圖獲得一個同步監(jiān)視器,但該同步監(jiān)視器正被其他線程所持有;線程在等待某個通知(notify);線程的生命周期被阻塞的線程會在合適的時候重新進入就緒狀態(tài),注意不是運行狀態(tài)。被阻塞線程的阻塞解除后,必須重新等待線程調(diào)度器再次調(diào)度它。當發(fā)生如下情況時,可解除阻塞,讓線程重新進入就緒狀態(tài)。調(diào)用sleep()方法的線程經(jīng)過了指定時間;線程調(diào)用的阻塞式IO方法已經(jīng)返回;線程成功地獲得了試圖取得的同步監(jiān)視器;線程正在等待某個通知時,其他線程發(fā)出了一個通知;2、運行和阻塞狀態(tài)線程的生命周期run()方法執(zhí)行完成,線程正常結束;線程拋出一個未捕獲的Exception或Error;直接調(diào)用該線程的stop()方法來結束該線程。注意:當主線程結束時,其他線程不受任何影響,并不會隨之結束。一旦子線程啟動起來后,它就擁有和主線程相同的地位。3、線程死亡為了測試某個線程是否已經(jīng)死亡,可以調(diào)用線程對象的isAlive()方法,當線程處于就緒、運行、阻塞3種狀態(tài)時,該方法將返回true;當線程處于新建、死亡2中狀態(tài)時,該方法將返回false。線程狀態(tài)轉換圖線程狀態(tài)轉換圖控制線程如果需要當前正在執(zhí)行的線程暫停一段時間,并進入阻塞狀態(tài),可通過調(diào)用Thread類的靜態(tài)方法sleep()方法來實現(xiàn)。即使系統(tǒng)中沒有其他可執(zhí)行的線程,處于sleep()中的線程也不會執(zhí)行,sleep()方法常用來暫停程序的執(zhí)行。1、線程睡眠(sleep)
Thread提供了讓一個線程等待另一個線程完成的方法—join()方法。當在某個程序執(zhí)行流中調(diào)用其他線程的join()方法時,調(diào)用線程將被阻塞,直到被join()方法join線程執(zhí)行完為止。2、join線程控制線程有一種線程,它是在后臺運行的,它的任務是為其他的線程提供服務,這種線程被稱為“后臺線程”,也叫“守護線程”或“精靈線程”。JVM的垃圾回收線程就是典型的后臺線程。后臺線程有個特征:如果所有的前臺線程都死亡,后臺線程會自動死亡。3、后臺線程(Daemon)調(diào)用Thread對象的setDaemon(true)方法可將指定線程設置為后臺線程,通過isDaemon()方法,可判斷指定線程是否為后臺線程。當要將某個線程設置為后臺線程時,必須要在該線程啟動之前,否則會引發(fā)IllegalThreadStateException異常??刂凭€程
yield()方法和sleep()方法相似,它也可以讓當前正在執(zhí)行的線程暫停,但它不會阻塞該線程,它只是將該線程轉入就緒狀態(tài)。即讓系統(tǒng)的線程調(diào)度器重新調(diào)度一次。完全可能的情況是:當某個線程調(diào)用了yield()方法暫停之后,線程調(diào)度器又將其調(diào)度出來重新執(zhí)行。4、線程讓步(yield)當某個線程調(diào)用了yield()方法暫停之后,只有優(yōu)先級與當前線程相同,或者優(yōu)先級比當前線程更高的處于就緒狀態(tài)的線程才會獲得執(zhí)行的機會??刂凭€程
sleep()方法和yield()方法的區(qū)別:sleep()方法暫停當前線程后,會給其他線程執(zhí)行機會,不會理會其他線程的優(yōu)先級;但yield()方法只會給優(yōu)先級相同,或優(yōu)先級更高的線程執(zhí)行機會;sleep()方法會將線程轉入阻塞狀態(tài),直到經(jīng)過阻塞時間才會轉入就緒狀態(tài);而yield()不會將線程轉入阻塞狀態(tài),它只是強制當前線程進入就緒狀態(tài);sleep()方法聲明拋出了InterruptedException異常,所以調(diào)用sleep()方法時要慢捕捉該異常,要么顯示聲明拋出該異常;而yield()方法則沒有聲明拋出任何異常;模擬賬戶存取錢
銀行賬戶類,提供相關屬性的setter和getter方法操作線程類的構造方法,傳入需要操作的賬戶、具體的操作以及操作的金額模擬賬戶存取錢線程執(zhí)行體測試方法模擬賬戶存取錢多線程操作時,會存在余額為負數(shù)的情況,為什么會這樣,如何解決?線程同步為了解決多個線程對共享資源的操作而導致的數(shù)據(jù)不一致問題,Java的多線程支持引入了同步監(jiān)視器,使用關鍵字synchronized。線程開始執(zhí)行同步代碼塊之前,必須先獲得對同步監(jiān)視器的鎖定。通用方法就是同步代碼塊,語法格式如下:synchronized(obj){ … //此處的代碼就是同步代碼塊}注意:任何時刻只能有一個線程可以獲得對同步監(jiān)視器的鎖定,當同步代碼塊執(zhí)行完成后,該線程會釋放對該同步監(jiān)視器的鎖定。同步方法同步方法與同步代碼塊相似,需要使用synchronized關鍵字修飾,對于同步方法而言,無須顯示指定同步監(jiān)視器,同步方法的同步監(jiān)視器是this,即當前對象本身。通過使用同步方法可方便實現(xiàn)線程安全的類,線程安全的類具有如下特征:該類的對象可以被多個線程安全地訪問;每個線程調(diào)用該對象的任意方法后都將得到正確結果;每個線程調(diào)用該對象的任意方法后,該對象狀態(tài)依然保持合理狀態(tài)。
不可變類總是線程安全的,因為它的對象狀態(tài)不可改變;但可變對象需要額外的方法(同步方法)來保證線程安全,這是以降低程序的運行效率為代價的。通常只對那些會改變共享資源的方法進行同步。釋放同步監(jiān)視器任何線程進入同步代碼塊、同步方法之前,必須先獲得對同步監(jiān)視器的鎖定,那么何時會釋放對同步監(jiān)視器的鎖定呢?當前線程的同步方法、同步代碼塊執(zhí)行結束,即釋放同步監(jiān)視器;當前線程在同步方法、同步代碼塊中遇到break、return終止了該代碼塊、該方法的繼續(xù)執(zhí)行,將會釋放同步監(jiān)視器;當前線程在同步方法、同步代碼塊中出現(xiàn)了未處理的Error或Exception,導致代碼塊或方法異常結束時,會釋放同步監(jiān)視器;當前線程執(zhí)行同步代碼塊或同步方式時,程序執(zhí)行了同步監(jiān)視器對象的wait()方法,則當前線程暫停,并釋放同步監(jiān)視器。注意:當同步代碼塊或同步方法中,調(diào)用Thread.sleep()、Thread.yield()方法來暫停當前線程的執(zhí)行,當前線程不會釋放同監(jiān)視器。同步監(jiān)視器引起的死鎖問題
Java線程死鎖是一個經(jīng)典的多線程問題,是指兩個或兩個以上的線程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進下去。導致死鎖必須滿足以下條件:互斥,即多個線程不能同時使用同一資源;占有等待,即某個線程必須同時擁有幾個資源才能執(zhí)行完成;非剝奪,即資源只能由線程執(zhí)行完主動釋放,而不能在別的線程沒有釋放資源的情況下,奪走其已占有的資源;環(huán)路等待條件:你等待我釋放資源,我等待你釋放資源,資源沒有滿足的線程無限期地等待。例如有兩個人A和B,面前擺放著食物,需要同時使用刀和叉才能食用,但現(xiàn)在只有一副刀叉,A獲得了刀,B獲得了叉。A在等待獲得叉,B在等待獲得刀。誰也不愿意給對方,這時候就進入僵持狀態(tài)即死鎖狀態(tài)。模擬死鎖的關鍵代碼程序執(zhí)行入口,主方法線程方法執(zhí)行體生產(chǎn)者消費者問題解決方案:讓生產(chǎn)者在緩沖區(qū)滿時休眠,等到下次消費者消耗緩沖區(qū)中的數(shù)據(jù)時,生產(chǎn)者才能被喚醒,開始往緩沖區(qū)添加數(shù)據(jù)。同樣,讓消費者在緩沖區(qū)空時進入休眠,等到生產(chǎn)者往緩沖區(qū)添加數(shù)據(jù)后,再喚醒消費者。
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度智能貸款產(chǎn)品居間服務合同
- 現(xiàn)代化實訓室設備配置全解析
- 2025年度貨車司機雇傭合同車輛管理與責任協(xié)議
- 科技引領下的農(nóng)村教育培訓資源整合
- 二零二五年度臍橙廣告代言合同書復合品牌形象版
- 系統(tǒng)化實驗室管理提升工作效率的新途徑
- 二零二五年度電力工程施工安全管理合同
- 2025年度化妝品銷售返利激勵合同
- 2025年度個人賬戶資金監(jiān)管與風險管理合同
- 2025年度資質借用及質量管理體系協(xié)議:食品行業(yè)資質借用合同
- 輸變電工程監(jiān)督檢查標準化清單-質監(jiān)站檢查
- 【超星學習通】馬克思主義基本原理(南開大學)爾雅章節(jié)測試網(wǎng)課答案
- 2024年中國工業(yè)涂料行業(yè)發(fā)展現(xiàn)狀、市場前景、投資方向分析報告(智研咨詢發(fā)布)
- 化工企業(yè)重大事故隱患判定標準培訓考試卷(后附答案)
- 工傷賠償授權委托書范例
- 食堂餐具炊具供貨服務方案
- 2024化工園區(qū)危險品運輸車輛停車場建設規(guī)范
- 自然科學基礎(小學教育專業(yè))全套教學課件
- 華為客服制度
- GB/T 42460-2023信息安全技術個人信息去標識化效果評估指南
- 工程與倫理課程
評論
0/150
提交評論