版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
Java多線程Java應(yīng)用開發(fā)與實(shí)踐
酒店管理系統(tǒng)的設(shè)計(jì)學(xué)習(xí)目標(biāo)理解進(jìn)程和線程的區(qū)別和聯(lián)系掌握線程的創(chuàng)建方法了解線程同步的概念了解線程調(diào)度的概念10.1進(jìn)程和線程10.2線程的創(chuàng)建10.3線程同步10.4線程調(diào)度10.5實(shí)訓(xùn)10多線程的練習(xí)和應(yīng)用目錄10.1進(jìn)程和線程進(jìn)程是一個在內(nèi)存中運(yùn)行的應(yīng)用程序。每個進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)程上下文),有它特定的進(jìn)程號。他們共享系統(tǒng)的內(nèi)存資源,進(jìn)程間的切換會有較大的開銷,一個進(jìn)程包含若干個線程,進(jìn)程是資源分配的最小單位。線程是進(jìn)程中的一個執(zhí)行任務(wù)(控制單元),負(fù)責(zé)當(dāng)前進(jìn)程中程序的執(zhí)行。一個進(jìn)程至少有一個線程,一個進(jìn)程可以運(yùn)行多個線程,多個線程共享進(jìn)程的堆和方法區(qū)資源,同時每個線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(PC),線程切換開銷小,因此線程也被稱為輕量級進(jìn)程。線程是CPU調(diào)度的最小單位。由于線程是操作系統(tǒng)直接支持的執(zhí)行單元,因此,高級語言通常都內(nèi)置多線程的支持,Java也不例外。10.1.1認(rèn)識進(jìn)程和線程10.1進(jìn)程和線程1)多線程技術(shù)使程序的響應(yīng)速度更快,因?yàn)橛脩艚缑婵梢栽谶M(jìn)行其它工作的同時一直處于活動狀態(tài);2)當(dāng)前沒有進(jìn)行處理的任務(wù)時可以將處理器時間讓給其它任務(wù);3)占用大量處理時間的任務(wù)可以定期將處理器時間讓給其它任務(wù);4)可以隨時停止任務(wù);5)可以分別設(shè)置各個任務(wù)的優(yōu)先級以優(yōu)化系統(tǒng)的性能。在以下情況下,最適合采用多線程處理:1)耗時或大量占用處理器的任務(wù)阻塞用戶界面操作;2)各個任務(wù)必須等待外部資源(如遠(yuǎn)程文件或Internet連接)。10.1.2多線程的特點(diǎn)10.1進(jìn)程和線程在Java中任何對象都有生命周期,線程也不例外,線程的創(chuàng)建即是線程的生命周期的開始,當(dāng)run()方法執(zhí)行完畢或者線程拋出一個未捕獲的異?;蛘咤e誤的時候,線程死亡。因此線程從創(chuàng)建到死亡的過程就是一個動態(tài)執(zhí)行的過程。10.1.3線程的生命周期及五種基本狀態(tài)10.1進(jìn)程和線程10.1.3線程的生命周期及五種基本狀態(tài)10.1進(jìn)程和線程新建狀態(tài)(new):當(dāng)線程對象對創(chuàng)建后,即進(jìn)入了新建狀態(tài),如: Threadt=newMyThread();就緒狀態(tài)(Runnable):當(dāng)調(diào)用線程對象的start()方法(t.start();),線程即進(jìn)入就緒狀態(tài)。處于就緒狀態(tài)的線程,只是說明此線程已經(jīng)做好了準(zhǔn)備,隨時等待CPU調(diào)度執(zhí)行,并不是說執(zhí)行了t.start()此線程立即就會執(zhí)行;運(yùn)行狀態(tài)(Running):當(dāng)CPU開始調(diào)度處于就緒狀態(tài)的線程時,此時線程才得以真正執(zhí)行,即進(jìn)入到運(yùn)行狀態(tài)。就緒狀態(tài)是進(jìn)入到運(yùn)行狀態(tài)的唯一入口。也就是說,線程要想進(jìn)入運(yùn)行狀態(tài)執(zhí)行,首先必須處于就緒狀態(tài)中;10.1.3線程的生命周期及五種基本狀態(tài)10.1進(jìn)程和線程阻塞狀態(tài)(Blocked):處于運(yùn)行狀態(tài)中的線程由于某種原因,暫時放棄對CPU的使用權(quán),停止執(zhí)行,此時進(jìn)入阻塞狀態(tài),直到其進(jìn)入到就緒狀態(tài),才有機(jī)會再次被CPU調(diào)用以進(jìn)入到運(yùn)行狀態(tài)。死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期。10.1.3線程的生命周期及五種基本狀態(tài)10.2線程的創(chuàng)建Thread類是java.lang包下的一個常用類,每一個Thread類的對象,就代表一個處于某種狀態(tài)的線程。Thread類用于操作線程,是所有涉及到線程的操作(如并發(fā))的基礎(chǔ)。創(chuàng)建線程比較常用的一種方法就是繼承Thread類。如果應(yīng)用系統(tǒng)只需要建立一條線程,而沒有什么其它特殊的要求,那么繼承Thread類無疑是較好的選擇。Thread類中的方法可分為實(shí)例方法和靜態(tài)方法,其中實(shí)例方法有start()方法,run()方法等,靜態(tài)方法有currentThread()方法,sleep(longmillis)方法等。10.2.1通過繼承Thread類創(chuàng)建線程10.2線程的創(chuàng)建1.start()方法start()用來啟動一個線程,當(dāng)調(diào)用start()方法后,系統(tǒng)才會開啟一個新的線程來執(zhí)行用戶定義的子任務(wù),在這個過程中,會為相應(yīng)的線程分配需要的資源。要注意,調(diào)用start方法的順序不代表線程啟動的順序,也就是CPU執(zhí)行哪個線程的代碼具有不確定性。10.2.1通過繼承Thread類創(chuàng)建線程10.2線程的創(chuàng)建2.run()方法這個方法是線程類調(diào)用start()后所執(zhí)行的方法,如果直接調(diào)用run()而不是start()方法,那么和普通方法一樣沒有區(qū)別。要注意,run()方法是不需要用戶來調(diào)用的,當(dāng)通過start()方法啟動一個線程之后,當(dāng)線程獲得了CPU執(zhí)行時間,便進(jìn)入run()方法體去執(zhí)行具體的任務(wù)。用start()方法來啟動線程,是真正實(shí)現(xiàn)了多線程,通過調(diào)用Thread類的start()方法來啟動一個線程,這時此線程處于就緒(可運(yùn)行)狀態(tài),并沒有運(yùn)行,一旦得到CPU時間片,就開始執(zhí)行run()方法,無需等待run()方法執(zhí)行完畢,即可繼續(xù)執(zhí)行下面的代碼。所以說:start()方法是真正實(shí)現(xiàn)了多線程,run()方法只是一個普通的方法。10.2.1通過繼承Thread類創(chuàng)建線程10.2線程的創(chuàng)建3.interrupt()方法使用這個方法不會中斷線程。實(shí)際上調(diào)用interrupt實(shí)際作用是在線程受到阻塞時拋出一個中斷信號,這樣線程就得以退出阻塞狀態(tài)。4.join()方法join方法會使得調(diào)用join方法的線程無限阻塞,直到調(diào)用join方法的線程銷毀為止,join方法內(nèi)部使用的是wait(),所以會釋放鎖。10.2.1通過繼承Thread類創(chuàng)建線程10.2線程的創(chuàng)建5.sleep(longmillis)方法sleep()方法是靜態(tài)方法,它的作用就是在指定的時間(單位是毫秒)讓正在執(zhí)行的線程休眠,不釋放鎖。后面小節(jié)有詳述。6.yield()方法暫停當(dāng)前執(zhí)行的線程對象,并執(zhí)行其他線程。這個暫停會放棄CPU資源,放棄的時間不確定。10.2.1通過繼承Thread類創(chuàng)建線程10.2線程的創(chuàng)建繼承Thread類的步驟如下:1)定義類繼承Thread類;2)重寫Thread類中的run()方法;重寫run()方法的目的是將需要該線程執(zhí)行的代碼存儲在run()方法運(yùn)行。3)調(diào)用線程的start方法。該方法有兩步:啟動線程,調(diào)用run()方法。10.2.1通過繼承Thread類創(chuàng)建線程10.2線程的創(chuàng)建classMyThreadextendsThread{ publicvoidrun(){ for(inti=0;i<10;i++){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); }//this.getName()獲取當(dāng)前線程
System.out.println(this.getName()); } }}10.2.1通過繼承Thread類創(chuàng)建線程10.2線程的創(chuàng)建publicclassDemo10_1{ publicstaticvoidmain(String[]args){ MyThreadthead1=newMyThread(); MyThreadthead2=newMyThread(); thead1.start(); thead2.start(); }}10.2.1通過繼承Thread類創(chuàng)建線程10.2線程的創(chuàng)建實(shí)現(xiàn)Runnable接口的步驟如下:1)定義類實(shí)現(xiàn)Runnable接口;2)實(shí)現(xiàn)Runnable接口中的run()方法,將線程要運(yùn)行的代碼放在該run()方法中;3)通過Thread類建立線程對象;4)將Runnable接口的子類對象作為實(shí)際參數(shù)傳遞給Thread類的構(gòu)造函數(shù)。自定義的run()方法所屬的對象是Runnable接口的子類對象。5)調(diào)用Thread類的start()方法開啟線程并調(diào)用Runnable接口子類的run()方法。10.2.2通過實(shí)現(xiàn)Runnable接口創(chuàng)建線程10.2線程的創(chuàng)建classMyThreadimplementsRunnable{ publicvoidrun(){ for(inti=0;i<10;i++){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } //Thread.currentThread()獲取當(dāng)前線程 System.out.println(Thread.currentThread().getName()); } }}10.2.2通過實(shí)現(xiàn)Runnable接口創(chuàng)建線程10.2線程的創(chuàng)建publicclassDemo10_2{ publicstaticvoidmain(String[]args){ MyThreadthread1=newMyThread(); MyThreadthread2=newMyThread(); Threadth1=newThread(thread1,"MyThread1"); Threadth2=newThread(thread2,"MyThread2"); th1.start(); th2.start(); }}10.2.2通過實(shí)現(xiàn)Runnable接口創(chuàng)建線程10.2線程的創(chuàng)建繼承Thread類和實(shí)現(xiàn)Runnable接口都可以創(chuàng)建線程。在繼承Thread的方式中,線程代碼是存放在Thread子類run()方法中,線程對象和線程任務(wù)耦合在一起。一旦創(chuàng)建Thread類的子類對象,既是線程對象,有又有線程任務(wù)。優(yōu)點(diǎn)是編寫簡單,可直接用this.getname()獲取當(dāng)前線程,不必使用Thread.currentThread()方法。但缺點(diǎn)也有,就是已經(jīng)繼承了Thread類后,無法再繼承其他類。實(shí)現(xiàn)Runnable接口的方式較為常用,實(shí)現(xiàn)Runnable接口的方式,更加的符合面向?qū)ο蟮乃枷耄壕€程分為兩部分,一部分線程對象,一部分線程任務(wù)。將線程任務(wù)單獨(dú)分離出來封裝成對象,存放在接口的子類的run()方法中,類型就是Runnable接口類型。此方式優(yōu)點(diǎn)是避免了單繼承的局限性、多個線程可以共享一個target對象,非常適合多線程處理同一份資源的情形。缺點(diǎn)是比較復(fù)雜、訪問線程必須使用Thread.currentThread()方法、無返回值。10.2.3繼承Thread類和實(shí)現(xiàn)Runnable接口的區(qū)別10.3線程同步線程同步就是指各個線程協(xié)同步調(diào),按預(yù)定的先后次序進(jìn)行運(yùn)行。這里的“同”字意思就是指協(xié)同、協(xié)助、互相配合。多線程通過特定的設(shè)置(如互斥量,事件對象,臨界區(qū))來控制線程之間的執(zhí)行順序(即所謂的同步)也可以說是在線程之間通過同步建立起執(zhí)行順序的關(guān)系,如果沒有同步,那線程之間是各自運(yùn)行各自的。線程同步的主要任務(wù)是使并發(fā)執(zhí)行的各線程之間能夠有效的共享資源和相互合作,從而使程序的執(zhí)行具有可再現(xiàn)性。通常,在多線程編程里面,一些敏感數(shù)據(jù)不允許被多個線程同時訪問,此時就使用同步訪問技術(shù),保證數(shù)據(jù)在任何時刻,最多有一個線程訪問,以保證數(shù)據(jù)的完整性。10.3.1線程同步10.3線程同步線程互斥是指對于共享的進(jìn)程系統(tǒng)資源,在各單個線程訪問時的排它性。當(dāng)有若干個線程都要使用某一共享資源時,任何時刻最多只允許一個線程去使用,其它要使用該資源的線程必須等待,直到占用資源者釋放該資源。線程互斥可以看成是一種特殊的線程同步。所以,可以看出,在多個線程之間都需要訪問共享資源(sharedresource)的時候就會出現(xiàn)互斥現(xiàn)象。10.3.2線程互斥10.3線程同步線程同步的機(jī)制有臨界區(qū)、互斥量、事件、信號量四種方式。1.臨界區(qū):在一段時間內(nèi)只允許一個線程訪問的資源就稱為臨界資源或獨(dú)占資源,計(jì)算機(jī)中大多數(shù)物理設(shè)備,進(jìn)程中的共享變量等待都是臨界資源,它們要求被互斥的訪問。每個進(jìn)程中訪問臨界資源的代碼稱為臨界區(qū)。在任意時刻只允許一個線程對共享資源進(jìn)行訪問,如果有多個線程試圖訪問公共資源,那么在有一個線程進(jìn)入后,其他試圖訪問公共資源的線程將被掛起,并一直等到進(jìn)入臨界區(qū)的線程離開,臨界區(qū)在被釋放后,其他線程才可以搶占。10.3.3線程同步機(jī)制10.3線程同步線程同步的機(jī)制有臨界區(qū)、互斥量、事件、信號量四種方式。2、互斥量:互斥量和臨界區(qū)很像,采用互斥對象機(jī)制,只有擁有互斥對象的線程才有訪問公共資源的權(quán)限。因?yàn)榛コ鈱ο笾挥幸粋€,所以能保證公共資源不會同時被多個線程同時訪問。當(dāng)前擁有互斥對象的線程處理完任務(wù)后必須將線程交出,以便其他線程訪問該資源。10.3.3線程同步機(jī)制10.3線程同步線程同步的機(jī)制有臨界區(qū)、互斥量、事件、信號量四種方式。3.信號量:信號量是維護(hù)0到指定最大值之間的同步對象。信號量狀態(tài)在其計(jì)數(shù)大于0時是有信號的,而其計(jì)數(shù)是0時是無信號的。信號量對象在控制上可以支持有限數(shù)量共享資源的訪問。4.事件:通過通知操作的方式來保持線程的同步,還可以方便實(shí)現(xiàn)對多個線程的優(yōu)先級比較的操作。10.3.3線程同步機(jī)制10.4線程調(diào)度線程可以劃分優(yōu)先級,線程的優(yōu)先級告訴CPU該線程的重要程度有多大。每個線程都具有優(yōu)先級,Java虛擬機(jī)根據(jù)線程的優(yōu)先級決定線程的執(zhí)行順序。程序會盡可能地先運(yùn)行優(yōu)先級高的那個程序,這樣使多線程合理共享CPU資源而不會產(chǎn)生沖突。通常優(yōu)先級高的線程得到的CPU資源較多,也是CPU優(yōu)先執(zhí)行優(yōu)先級較高的線程對象中的任務(wù)。程序盡可能運(yùn)行優(yōu)先級高的程序,并不意味著優(yōu)先級較低的線程絕對不會運(yùn)行。若程序的優(yōu)先級較低,只不過表示它被允許的運(yùn)行的幾率小一些而已。Java中的線程優(yōu)先級分為1(Thread.MIN_PRIORITY)-10(Thread.MAX_PRIORITY),數(shù)字越大,優(yōu)先級越高10.4.1線程優(yōu)先級的設(shè)置10.4線程調(diào)度線程休眠通常是調(diào)用Thread.sleep(毫秒數(shù))方法,讓當(dāng)前運(yùn)行的線程進(jìn)入TIMED_WAITING(sleeping)阻塞狀態(tài),該方法使當(dāng)前線程進(jìn)入休眠狀態(tài),直到休眠設(shè)置的毫秒數(shù)后由系統(tǒng)喚醒,sleep方法上有一個異常。如果打斷休眠就會拋出這個異常。publicstaticvoidsleep(longmills)throwsInterruptedException10.4.2線程休眠10.4線程調(diào)度Java允許多線程并發(fā)控制,當(dāng)多個線程同時操作一個可共享資源變量時(如對其進(jìn)行增刪改查操作),會導(dǎo)致數(shù)據(jù)不準(zhǔn)確,而且相互之間產(chǎn)生沖突。加入同步鎖以避免該線程在沒有完成操作前被其他線程調(diào)用,從而保證該變量的唯一性和準(zhǔn)確性。在程序中需要完成下面兩個操作:1)把競爭訪問的資源標(biāo)識為private;2)同步那些修改變量的代碼,使用synchronized關(guān)鍵字同步方法或代碼。10.4.3線程同步10.4線程調(diào)度從本質(zhì)上說,synchronized是一種鎖機(jī)制,它是為一個對象或者一個類標(biāo)明一個鎖,當(dāng)線程想要執(zhí)行相應(yīng)的synchronized修飾的代碼塊時,它需要獲得synchronized修飾的對象或者類的鎖,這個就是CPU的使用權(quán)。只有拿到了鎖才可以被CPU調(diào)度,獲得處理權(quán)。當(dāng)synchronized代碼塊執(zhí)行結(jié)束后,這個線程就要釋放相應(yīng)的鎖。CPU可以把這個鎖分給其它的線程。synchronized可以作為函數(shù)的修飾符,也可作為函數(shù)內(nèi)的語句,即同步函數(shù)或同步代碼塊來實(shí)現(xiàn)線程同步,因此它們都是同步鎖。10.4.3線程同步10.4線程調(diào)度1.join()方法在很多情況下,主線程生成并起動了子線程,如果子線程里要進(jìn)行大量的耗時的運(yùn)算,主線程往往將于子線程之前結(jié)束,但是如果主線程處理完其他的事務(wù)后,需要用到子線程的處理結(jié)果,也就是主線程需要等待子線程執(zhí)行完成之后再結(jié)束,這個時候就要用到j(luò)oin()方法了。join()方法主要作用是掛起(即插隊(duì))。10.4.4線程常用方法10.4線程調(diào)度2.yield()方法yield()方法可以對當(dāng)前線程進(jìn)行臨時暫停(讓線程將資源釋放出來),供所有線程競爭。3.wait()方法和notify()方法wait()方法類似sleep(),不同的是,wait()會先釋放鎖住的對象,然后再執(zhí)行等待的動作。注意,這個函數(shù)屬于Object類。另外,由于wait()所等待的對象必須先鎖住,因此,它只能用在同步化程序段或者同步化方法內(nèi),否則,會拋出異常IllegalMonitorStateException。10.4.4線程常用方法10.4線程調(diào)度兩個或者多個線程同時想要去獲取共享資源的鎖,但每個線程都要等其他線程把他們各自的鎖給釋
溫馨提示
- 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年江蘇貨運(yùn)從業(yè)資格證考試模擬題及答案解析
- 物流運(yùn)輸報(bào)價合同范例
- 婚宴酒席合同范例
- 2025年鄭州a2貨運(yùn)從業(yè)資格證考試
- 棉花機(jī)械轉(zhuǎn)讓合同范例
- 唐山職業(yè)技術(shù)學(xué)院《衛(wèi)生毒理學(xué)A》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025年茂名貨運(yùn)從業(yè)資格證模擬考試下載什么軟件
- 唐山職業(yè)技術(shù)學(xué)院《檔案管理學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 培訓(xùn)學(xué)校兼職會計(jì)合同范例
- 呼吸系統(tǒng)疾病診療規(guī)范
- 夜聽電臺情感故事【十二篇】
- Unit 1 What's he like Part B Let's learn(說課稿)人教PEP版英語五年級上冊
- 2023年全國乙卷筆試部分講解課件 【高效課堂+精研精講】 高考英語復(fù)習(xí)
- 國開2023年春《人文英語4》機(jī)考網(wǎng)考期末復(fù)習(xí)資料參考答案
- 教師追悼會家屬答謝詞(三篇)
- 初三英語中考模擬試卷
- 酒店業(yè)輕資產(chǎn)運(yùn)營模式案例研究
- 《卓有成效的管理者》讀書分享
- 員工食堂承包合同、考核細(xì)則、考核評分表
- 優(yōu)秀管理者評選方案
評論
0/150
提交評論