Java程序設(shè)計(jì)應(yīng)用開發(fā)教程 課件 7.2 多線程_第1頁
Java程序設(shè)計(jì)應(yīng)用開發(fā)教程 課件 7.2 多線程_第2頁
Java程序設(shè)計(jì)應(yīng)用開發(fā)教程 課件 7.2 多線程_第3頁
Java程序設(shè)計(jì)應(yīng)用開發(fā)教程 課件 7.2 多線程_第4頁
Java程序設(shè)計(jì)應(yīng)用開發(fā)教程 課件 7.2 多線程_第5頁
已閱讀5頁,還剩14頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

單元7

網(wǎng)絡(luò)編程與多線程7.2多線程程序設(shè)計(jì)

任務(wù)7.2多用戶登錄任務(wù)描述多個(gè)用戶登錄自動出貨管理系統(tǒng),需要在服務(wù)器與多個(gè)客戶端之間進(jìn)行通信,效果如圖7-2所示。多線程是Java的一個(gè)重要特性。在服務(wù)器啟用多線程模式時(shí),可以通過線程來處理不同用戶發(fā)送的信息。當(dāng)每個(gè)用戶登錄時(shí),從客戶端發(fā)起登錄請求,將登錄用戶數(shù)據(jù)傳遞到服務(wù)器,由服務(wù)器顯示用戶登錄信息,并將信息響應(yīng)給客戶端(登錄成功或登錄失?。?。當(dāng)有多個(gè)客戶端連接到服務(wù)器時(shí),服務(wù)器會為每個(gè)客戶端建立一個(gè)線程來處理接收到信息,而不會產(chǎn)生阻塞,實(shí)現(xiàn)一個(gè)服務(wù)器與多個(gè)客戶端的通信。圖7-2多用戶登錄知識目標(biāo)了解線程與進(jìn)程的區(qū)別。熟悉實(shí)現(xiàn)多線程的方法。熟悉線程同步的方法。能力目標(biāo)能通過繼承Thread類實(shí)現(xiàn)多線程。能通過Runnable接口實(shí)現(xiàn)多線程。能使用方法或代碼塊實(shí)現(xiàn)線程同步。能使用多線程和套接字實(shí)現(xiàn)服務(wù)器服務(wù)多個(gè)客戶的操作。素養(yǎng)目標(biāo)良好的職業(yè)道德規(guī)范。培養(yǎng)嚴(yán)謹(jǐn)?shù)墓ぷ髯黠L(fēng)和創(chuàng)新精神。任務(wù)7.2多用戶登錄在高速公路收費(fèi)匝道上,經(jīng)常會看到排成長龍的車隊(duì)。如果讓你來緩解這一擁塞的交通狀況,你的方案是什么?在一個(gè)行政收費(fèi)大廳里,如果只有一個(gè)辦事窗ロ,等待辦事的客戶很多。解決方案是?進(jìn)程可以理解為一個(gè)應(yīng)用程序的執(zhí)行過程,應(yīng)用程序一旦執(zhí)行,就是一個(gè)進(jìn)程。如果把進(jìn)程比作一個(gè)收費(fèi)站,多個(gè)收費(fèi)匝道就可以比作線程。如果將行政大廳比喻為一個(gè)進(jìn)程,每個(gè)辦事窗口就是一個(gè)線程。

相關(guān)知識多線程:多線程在Windows操作系統(tǒng)中的運(yùn)行進(jìn)程1進(jìn)程3線程1線程3線程2線程5線程4線程n…進(jìn)程2在CPU執(zhí)行進(jìn)程2的時(shí)間片內(nèi)圖7-3多線程在Windows操作系統(tǒng)中的運(yùn)行模式Windows操作系統(tǒng)是多任務(wù)操作系統(tǒng),它以進(jìn)程為單位。每個(gè)獨(dú)立執(zhí)行的程序都被稱為進(jìn)程。比如:正在運(yùn)行的QQ是一個(gè)進(jìn)程、正在運(yùn)行的企業(yè)微信是一個(gè)進(jìn)程,正在運(yùn)行的Eclipse也是一個(gè)進(jìn)程,每個(gè)進(jìn)程都可以包含多個(gè)線程。系統(tǒng)可以分配給每個(gè)進(jìn)程一段使用CPU的時(shí)間(也可以稱為CPU時(shí)間片),CPU在這段時(shí)間中執(zhí)行某個(gè)進(jìn)程(同理,同一個(gè)進(jìn)程種每個(gè)線程也可以得到一小段執(zhí)行時(shí)間,這樣一個(gè)進(jìn)程就可以具有多個(gè)并非執(zhí)行的線程),然后下一個(gè)CPU時(shí)間片又執(zhí)行另一個(gè)進(jìn)程。進(jìn)程是并發(fā)執(zhí)行程序在執(zhí)行過程中資源分配和管理的基本單位(資源分配的最小單位),每個(gè)進(jìn)程都有自己獨(dú)立的地址空間。線程是比進(jìn)程更小的執(zhí)行單元,是進(jìn)程中的一個(gè)實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位。一個(gè)進(jìn)程在執(zhí)行過程中,可以產(chǎn)生多個(gè)線程。同一類線程共享代碼和數(shù)據(jù)空間,每個(gè)線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(PC),線程切換開銷小。多線程的機(jī)制則指可以同時(shí)運(yùn)行多個(gè)程序塊(進(jìn)程的多條路徑),在Java中被稱為并發(fā)機(jī)制。采用多線程機(jī)制可以是計(jì)算機(jī)資源得到更充分的使用,多線程可以使程序在同一時(shí)間內(nèi)完成很多任務(wù)操作。進(jìn)程與線程的概念classTestThread{

public

voidrun(){

for(int

i=0;i<5;++i){System.out.println("TestThread在運(yùn)行"

);

}

}}public

classMainClass{public

static

voidmain(Stringargs[]){

newTestThread().run();//創(chuàng)建一個(gè)新線程對象,并輸出

//循環(huán)輸出

for(int

i=0;i<5;++i){System.out.println("main線程在運(yùn)行"

);

}

}}引入:單一線程的運(yùn)行流程要想運(yùn)行main()方法中的for循環(huán),必須等ThreadDemo類中的run()方法執(zhí)行完。即使該代碼塊不依賴前面的代碼塊的計(jì)算機(jī)結(jié)果,它也“無可奈何”地必須等待,這就是單一線程的缺陷。如何使兩個(gè)代碼塊能否交替輸出呢?答案是肯定的,就是Java多線程的作用了。Thread類的構(gòu)造方法

publicThread():

創(chuàng)建一個(gè)新的線程對象

publicThread(StringthreadName):創(chuàng)建一個(gè)名稱為threadName的線程對象Thread類的常用方法Interrupt():中斷線程

run():如果該線程是使用獨(dú)立的Runnable對象構(gòu)造的,則調(diào)用Runnable對象的run()方法,否則,該方法不執(zhí)行任何操作并返回。start():使該線程開始執(zhí)行,Java虛擬機(jī)調(diào)用該線程的run()方法。sleep():在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行)繼承java.lang.Thread類Thread類是Java.lang包中的一個(gè)類,Thread類的對象用來代表線程實(shí)現(xiàn)多線程的方法:通過繼承Thread類創(chuàng)建、啟動并執(zhí)行一個(gè)線程的步驟如下:創(chuàng)建一個(gè)繼承Thread類的子類覆寫Thread類的run()方法。創(chuàng)建線程類的一個(gè)對象。通過線程類的對象調(diào)用start()方法啟動線程(啟動之后會自動調(diào)用覆寫的run()方法執(zhí)行線程)繼承java.lang.Thread類繼承java.lang.Thread類public

classThreadDemoTestextendsThread{privateStringname;

publicThreadDemoTest(Stringname){

this.name=name;

}

//重寫run()方法

public

voidrun(){

for(int

i=0;i<5;i++){System.out.println(name+"運(yùn)行:"

+i);

try{

sleep((int)Math.random()*10);//正在執(zhí)行線程休眠}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}public

static

voidmain(String[]args){ThreadDemoTestt1=newThreadDemoTest("A"

);//創(chuàng)建線程對象t1ThreadDemoTestt2=newThreadDemoTest("B"

);//創(chuàng)建線程對象t2t1.start();//啟動線程t1t2.start();//啟動線程t2}}所有的線程對象都必須是Thread或者其子類的實(shí)例。創(chuàng)建一個(gè)新的線程t1,

此線程進(jìn)入新建狀態(tài);調(diào)用start()方法使得線程進(jìn)入就緒狀態(tài)使用繼承Thread類的子類來創(chuàng)建線程類時(shí),多個(gè)線程無法共享線程類的實(shí)例變量實(shí)現(xiàn)java.lang.Runnable接口如果當(dāng)前類不僅要繼承其他類(非Thread類),還要實(shí)現(xiàn)多線程,那么如何處理呢?使用Runnable接口啟動新線程

創(chuàng)建Runnable對象;使用參數(shù)為Runnable對象的構(gòu)造方法創(chuàng)建Thread對象;調(diào)用start()方法啟動線程。Thread對象Runnable

對象啟動線程,執(zhí)行run()方法中的代碼。根據(jù)Runnable對象創(chuàng)建Thread對象調(diào)用start()方法實(shí)現(xiàn)Runnable接口創(chuàng)建線程的流程實(shí)現(xiàn)java.lang.Runnable接口classRunnableThreadDemoimplementsRunnable{

public

voidrun(){

for(int

i=0;i<5;i++){System.out.println(Thread.currentThread().getName()

+"運(yùn)行"+i);

try{

Thread.sleep(1000);//睡眠1秒}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}}public

classRunnableThread{public

static

voidmain(Stringargs[]){

RunnableThreadDemo

th=newRunnableThreadDemo();

newThread(th).start();//使用Thread類的start方法啟動線程

for(int

i=0;i<5;i++){System.out.println("main線程在運(yùn)行"

);

try{

Thread.sleep(1000);//睡眠1秒}catch(InterruptedExceptione){

e.printStackTrace();}

}

}}靜態(tài)方法currentThread(),返回值是當(dāng)前正在執(zhí)行該方法的線程實(shí)例。顯示Runnable接口相對于繼承Thread類顯著優(yōu)勢:避免了由于Java的單繼承特性帶來的局限性??墒嵌鄠€(gè)線程共享相同的資源,以達(dá)到資源共享的目的。線程生命周期及狀態(tài)線程具有生命周期,其中包含5種狀態(tài),分別為新建狀態(tài)、就緒狀態(tài)、運(yùn)行狀態(tài)、暫停狀態(tài)(包含休眠、等待和阻塞)和死亡狀態(tài)。Thread.sleep()方法Object.wait()方法Object.notify()Object.join()方法Thread.yield()案例:交通紅綠燈根據(jù)所給代碼,補(bǔ)充完整,實(shí)現(xiàn)多線程在模擬紅綠燈變化場景。多線程的同步如何解決資源共享的問題?共享資源加鎖所有解決多線程資源沖突問題的方法,都是在給定時(shí)間只允許一個(gè)線程訪問共享資源,相當(dāng)于給共享資源加道鎖。使用代碼塊實(shí)現(xiàn)線程同步使用方法實(shí)現(xiàn)線程同步多線程的同步使用代碼塊實(shí)現(xiàn)線程同步同步機(jī)制使用synchronized關(guān)鍵。每個(gè)Java對象都有一個(gè)內(nèi)置鎖,如果代碼塊使用synchronized關(guān)鍵字進(jìn)行聲明,通過鎖定指定的對象,來對同步塊中包含的代碼進(jìn)行同步,則使用該關(guān)鍵字的代碼塊稱為同步塊,也稱為臨界區(qū)。synchronized(Object)同步代碼與同步方法鎖的是對象,而不是代碼。如果某個(gè)對象被同步代碼塊或同步方法鎖住了,那么其他使用該對象的代碼必須等待,直到該對象的鎖被釋放。public

classSynchronizedTestimplementsRunnable{int

num

=10;//設(shè)置當(dāng)前總票數(shù)public

voidrun(){while(true){//設(shè)置無限循環(huán)synchronized(this){//設(shè)置同步代碼塊if(num>0){//判斷當(dāng)前票數(shù)是否大于0try{Thread.sleep(100);//使當(dāng)前線程休眠100毫秒}catch(Exceptione){e.printStackTrace();}System.out.println(Thread.currentThread().getName()+“---票數(shù)"

+num--;}}}}public

static

voidmain(String[]args){SynchronizedTestt=newSynchronizedTest();ThreadtA=newThread(t,"線程1");ThreadtB=newThread(t,"線程2");ThreadtC=newThread(t,"線程3");ThreadtD=newThread(t,"線程4");tA.start();//分別啟動線程tB.start();tC.start();tD.start();}}示例:使用同步塊模擬售票系統(tǒng),解決一票多賣的現(xiàn)象運(yùn)行結(jié)果:每個(gè)Java對象都有一個(gè)內(nèi)置鎖,如果方法使用synchronized關(guān)鍵字進(jìn)行聲明,內(nèi)置鎖就會保護(hù)整個(gè)方法。在在調(diào)用該方法前,需要獲得內(nèi)置鎖,否則程序?qū)幱谧枞麪顟B(tài)。使用方法實(shí)現(xiàn)線程同步publicsynchronizedvoidf(){}多線程的同步示例:使用同步方法解決模擬售票系統(tǒng)的資源共享問題。public

classSynchronizedTest1implementsRunnable{int

num

=10;//設(shè)置當(dāng)前總票數(shù)public

synchronized

voidf(){if(num>0){//判斷當(dāng)前票數(shù)是否大于0

try{Thread.

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論