Java語(yǔ)言程序設(shè)計(jì)(自考)課件 第十章 多線(xiàn)程_第1頁(yè)
Java語(yǔ)言程序設(shè)計(jì)(自考)課件 第十章 多線(xiàn)程_第2頁(yè)
Java語(yǔ)言程序設(shè)計(jì)(自考)課件 第十章 多線(xiàn)程_第3頁(yè)
Java語(yǔ)言程序設(shè)計(jì)(自考)課件 第十章 多線(xiàn)程_第4頁(yè)
Java語(yǔ)言程序設(shè)計(jì)(自考)課件 第十章 多線(xiàn)程_第5頁(yè)
已閱讀5頁(yè),還剩54頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第十章多線(xiàn)程

學(xué)習(xí)目標(biāo)能夠敘述線(xiàn)程和多線(xiàn)程的概念,線(xiàn)程各種狀態(tài)之間轉(zhuǎn)換的條件,線(xiàn)程的優(yōu)先級(jí)能夠使用Thread類(lèi)和Runnabe接口創(chuàng)建線(xiàn)程能夠?qū)€(xiàn)程進(jìn)行控制,實(shí)現(xiàn)線(xiàn)程之間的互斥和同步本章主要內(nèi)容線(xiàn)程和多線(xiàn)程12線(xiàn)程的基本控制3創(chuàng)建線(xiàn)程線(xiàn)程的互斥4線(xiàn)程的同步5線(xiàn)程的概念程序是一段靜態(tài)的代碼,它是應(yīng)用程序執(zhí)行的藍(lán)本一個(gè)進(jìn)程既包括其所要執(zhí)行的指令,也包括了執(zhí)行指令所需的任何系統(tǒng)資源,如CPU、內(nèi)存空間、I/O端口等,不同進(jìn)程所占用的系統(tǒng)資源相對(duì)獨(dú)立線(xiàn)程是進(jìn)程執(zhí)行過(guò)程中產(chǎn)生的多條執(zhí)行線(xiàn)索,是比進(jìn)程單位更小的執(zhí)行單位線(xiàn)程的結(jié)構(gòu)在Java中,線(xiàn)程由3部分組成:虛擬CPU,封裝在java.lang.Thread類(lèi)中,它控制著整個(gè)線(xiàn)程的運(yùn)行執(zhí)行的代碼,傳遞給Thread類(lèi),由Thread類(lèi)控制按序執(zhí)行處理的數(shù)據(jù),傳遞給Thread類(lèi),是在代碼執(zhí)行過(guò)程中所要處理的數(shù)據(jù)當(dāng)一個(gè)線(xiàn)程被構(gòu)造時(shí),它由構(gòu)造方法參數(shù)、執(zhí)行代碼、操作數(shù)據(jù)來(lái)初始化一個(gè)線(xiàn)程所執(zhí)行的代碼與其他線(xiàn)程可以相同也可以不同一個(gè)線(xiàn)程訪(fǎng)問(wèn)的數(shù)據(jù)與其他線(xiàn)程可以相同也可以不同多線(xiàn)程的優(yōu)勢(shì)使用多線(xiàn)程可以在線(xiàn)程間直接共享數(shù)據(jù)和資源,而多進(jìn)程之間不能做到這一點(diǎn)使用多線(xiàn)程適合于開(kāi)發(fā)有多種交互接口的程序多線(xiàn)程的機(jī)制可以減輕編寫(xiě)交互頻繁、涉及面多的程序的困難,如偵聽(tīng)網(wǎng)絡(luò)端口的程序線(xiàn)程的狀態(tài)線(xiàn)程一共有4種狀態(tài),分別是新建、可運(yùn)行狀態(tài)、死亡及阻塞新建線(xiàn)程對(duì)象剛剛創(chuàng)建,還沒(méi)有啟動(dòng),此時(shí)還處于不可運(yùn)行狀態(tài)此時(shí)剛創(chuàng)建的線(xiàn)程處于新建狀態(tài),但已有了相應(yīng)的內(nèi)存空間以及其它資源可運(yùn)行狀態(tài)此時(shí)的線(xiàn)程已經(jīng)啟動(dòng),線(xiàn)程可能正在運(yùn)行,也可能沒(méi)有運(yùn)行,只要CPU一空閑,馬上就會(huì)運(yùn)行可以運(yùn)行但沒(méi)在運(yùn)行的線(xiàn)程都排在一個(gè)隊(duì)列中,這個(gè)隊(duì)列稱(chēng)為就緒隊(duì)列可運(yùn)行狀態(tài)中,正在運(yùn)行的線(xiàn)程處于運(yùn)行狀態(tài),等待運(yùn)行的線(xiàn)程處于就緒狀態(tài)一般地,單CPU情況下,最多只有一個(gè)線(xiàn)程處于運(yùn)行狀態(tài),可能會(huì)有多個(gè)線(xiàn)程處于就緒狀態(tài)調(diào)用線(xiàn)程的start()方法可使線(xiàn)程處于“可運(yùn)行”狀態(tài)死亡線(xiàn)程死亡的原因有兩個(gè)一是run()方法中最后一個(gè)語(yǔ)句執(zhí)行完畢二是當(dāng)線(xiàn)程遇到異常退出時(shí)便進(jìn)入了死亡狀態(tài)阻塞一個(gè)正在執(zhí)行的線(xiàn)程因特殊原因,被暫停執(zhí)行,就進(jìn)入阻塞狀態(tài)阻塞時(shí)線(xiàn)程不能進(jìn)入就緒隊(duì)列排隊(duì),必須等到引起阻塞的原因消除,才可重新進(jìn)入隊(duì)列排隊(duì)引起阻塞的原因很多,不同原因要用不同的方法解除sleep()和wait()是兩個(gè)常用的引起阻塞的方法中斷線(xiàn)程在程序中常常調(diào)用interrupt()來(lái)終止線(xiàn)程interrupt()不僅可中斷正在運(yùn)行的線(xiàn)程,而且也能中斷處于blocked狀態(tài)的線(xiàn)程interrupt()會(huì)拋出InterruptedException異常測(cè)試線(xiàn)程是否被中斷的方法voidinterrupt()向一個(gè)線(xiàn)程發(fā)送一個(gè)中斷請(qǐng)求,同時(shí)把這個(gè)線(xiàn)程的“interrupted”狀態(tài)置為true。若該線(xiàn)程處于“blocked”狀態(tài),會(huì)拋出InterruptedException異常staticbooleaninterrupted()檢測(cè)當(dāng)前線(xiàn)程是否已被中斷,并重置狀態(tài)“interrupted”值。即如果連續(xù)兩次調(diào)用該方法,則第二次調(diào)用將返回falsebooleanisInterrupted()檢測(cè)當(dāng)前線(xiàn)程是否已被中斷,不改變狀態(tài)“interrupted”值第二節(jié)創(chuàng)建線(xiàn)程創(chuàng)建線(xiàn)程有兩種方法繼承Thread類(lèi)創(chuàng)建線(xiàn)程實(shí)現(xiàn)Runnable接口創(chuàng)建線(xiàn)程繼承Thread類(lèi)java.lang.Thread是Java中用來(lái)表示線(xiàn)程的類(lèi)如果將一個(gè)類(lèi)定義為T(mén)hread的子類(lèi),那么這個(gè)類(lèi)的對(duì)象就可以用來(lái)表示線(xiàn)程類(lèi)Thread中典型的構(gòu)造方法Thread(ThreadGroupgroup,Runnabletarget,Stringname)name作為新線(xiàn)程的名稱(chēng),且是線(xiàn)程組group中的一員target必須實(shí)現(xiàn)接口Runnable,它是另一個(gè)線(xiàn)程對(duì)象創(chuàng)建線(xiàn)程的過(guò)程從Thread類(lèi)派生出一個(gè)子類(lèi),在類(lèi)中實(shí)現(xiàn)run()classLefthandextendsThread{ publicvoidrun(){……} //線(xiàn)程體}然后用該類(lèi)創(chuàng)建一個(gè)對(duì)象Lefthandleft=newLefthand();用start()方法啟動(dòng)線(xiàn)程left.start();程序10.1實(shí)現(xiàn)Runnable接口創(chuàng)建線(xiàn)程Runnable是Java中用以實(shí)現(xiàn)線(xiàn)程的接口,從任何實(shí)現(xiàn)線(xiàn)程功能的類(lèi)都必須實(shí)現(xiàn)該接口Thread類(lèi)實(shí)際上就是因?yàn)閷?shí)現(xiàn)了Runnable接口,所以它的子類(lèi)才相應(yīng)具有線(xiàn)程功能Runnable接口中只定義了一個(gè)方法就是run()方法,也就是線(xiàn)程體用Runnable()接口實(shí)現(xiàn)多線(xiàn)程時(shí),也必須實(shí)現(xiàn)run()方法,也需要使用start()啟動(dòng)線(xiàn)程編寫(xiě)線(xiàn)程體publicclassxyzimplementsRunnable{ inti; publicvoidrun(){ while(true){ System.out.println("Hello"+i++); } }}利用類(lèi)xyz可以構(gòu)造一個(gè)線(xiàn)程Runnabler=newxyz();Threadt=newThread(r);程序10.2創(chuàng)建線(xiàn)程兩種方法的適用條件適用于采用實(shí)現(xiàn)Runnable接口方法的情況因?yàn)镴ava只允許單繼承,如果一個(gè)類(lèi)已經(jīng)繼承了Thread,就不能再繼承其他類(lèi),在一些情況下,這就被迫采用實(shí)現(xiàn)Runnable的方法另外,由于原來(lái)的線(xiàn)程采用的是實(shí)現(xiàn)Runnable接口的方法,可能會(huì)出于保持程序風(fēng)格的一貫性而繼續(xù)使用這種方法創(chuàng)建線(xiàn)程兩種方法的適用條件適用于采用繼承Thread方法的情況當(dāng)一個(gè)run()方法置于Thread類(lèi)的子類(lèi)中時(shí),this實(shí)際上引用的是控制當(dāng)前運(yùn)行系統(tǒng)的Thread實(shí)例,所以,代碼不必寫(xiě)得像下面這樣繁瑣:Thread.currentThread().getState();而可簡(jiǎn)單地寫(xiě)為:getState();可以直接調(diào)用Thread類(lèi)中的方法,代碼直觀,所以許多Java程序員愿意使用繼承Thread的方法第三節(jié)線(xiàn)程的基本控制線(xiàn)程的啟動(dòng)要使線(xiàn)程真正在Java環(huán)境中運(yùn)行,必須通過(guò)方法start()來(lái)啟動(dòng)start()方法也在Thread類(lèi)中線(xiàn)程的操作方法start()啟動(dòng)線(xiàn)程對(duì)象,讓線(xiàn)程從新建狀態(tài)轉(zhuǎn)為就緒狀態(tài)run()用來(lái)定義線(xiàn)程對(duì)象被調(diào)度之后所執(zhí)行的操作,用戶(hù)必須重寫(xiě)run()方法yield()強(qiáng)制終止線(xiàn)程的執(zhí)行isAlive()測(cè)試當(dāng)前線(xiàn)程是否在活動(dòng)sleep(intmillsecond)使線(xiàn)程休眠一段時(shí)間,時(shí)間長(zhǎng)短由millsecond決定,單位為毫秒voidwait()使線(xiàn)程處于等待狀態(tài)線(xiàn)程的調(diào)度雖然就緒線(xiàn)程已經(jīng)可以運(yùn)行,但這并不意味著這個(gè)線(xiàn)程一定能夠立刻運(yùn)行CPU在同一時(shí)間只能分配給一個(gè)線(xiàn)程做一件事那么當(dāng)有多于一個(gè)的線(xiàn)程工作時(shí),CPU是如何分配的?這就是線(xiàn)程的調(diào)度問(wèn)題在Java中,線(xiàn)程調(diào)度通常是搶占式,而不是時(shí)間片式搶占式調(diào)度是指可能有多個(gè)線(xiàn)程準(zhǔn)備運(yùn)行,但只有一個(gè)在真正運(yùn)行一個(gè)線(xiàn)程獲得執(zhí)行權(quán),這個(gè)線(xiàn)程將持續(xù)運(yùn)行下去,直到它運(yùn)行結(jié)束或因?yàn)槟撤N原因而阻塞,再或者有另一個(gè)高優(yōu)先級(jí)線(xiàn)程就緒,最后一種情況稱(chēng)為低優(yōu)先級(jí)線(xiàn)程被高優(yōu)先級(jí)線(xiàn)程所搶占線(xiàn)程調(diào)度采用的優(yōu)先級(jí)策略?xún)?yōu)先級(jí)高的先執(zhí)行,優(yōu)先級(jí)低的后執(zhí)行每個(gè)線(xiàn)程創(chuàng)建時(shí)都會(huì)被自動(dòng)分配一個(gè)優(yōu)先級(jí),默認(rèn)時(shí),繼承其父類(lèi)的優(yōu)先級(jí)任務(wù)緊急的線(xiàn)程,其優(yōu)先級(jí)較高同優(yōu)先級(jí)的線(xiàn)程按“先進(jìn)先出”的調(diào)度原則與線(xiàn)程優(yōu)先級(jí)有關(guān)的靜態(tài)量MAX_PRIORITY:最高優(yōu)先級(jí),值為10MIN_PRIORITY:最低優(yōu)先級(jí),值為1NORM_PRIORITY:默認(rèn)優(yōu)先級(jí),值為5有關(guān)優(yōu)先級(jí)的常用方法voidsetPriority(intnewPriority)重置線(xiàn)程優(yōu)先級(jí)intgetPriority()獲得當(dāng)前線(xiàn)程的優(yōu)先級(jí)staticvoidyield()暫停當(dāng)前正在執(zhí)行的線(xiàn)程,即讓當(dāng)前線(xiàn)程放棄執(zhí)行權(quán)線(xiàn)程被阻塞的原因可能是因?yàn)閳?zhí)行了Thread.sleep()調(diào)用,故意讓它暫停一段時(shí)間也可能是因?yàn)樾枰却粋€(gè)較慢的外部設(shè)備例如磁盤(pán)或用戶(hù)操作的鍵盤(pán)線(xiàn)程隊(duì)列所有被阻塞的線(xiàn)程按次序排列,組成一個(gè)阻塞隊(duì)列所有就緒但沒(méi)有運(yùn)行的線(xiàn)程則根據(jù)其優(yōu)先級(jí)排入一個(gè)就緒隊(duì)列當(dāng)CPU空閑時(shí),如果就緒隊(duì)列不空,隊(duì)列中第一個(gè)具有最高優(yōu)先級(jí)的線(xiàn)程將運(yùn)行當(dāng)一個(gè)線(xiàn)程被搶占而停止運(yùn)行時(shí),它的運(yùn)行態(tài)被改變并放到就緒隊(duì)列的隊(duì)尾同樣,一個(gè)被阻塞的線(xiàn)程就緒后通常也放到就緒隊(duì)列的隊(duì)尾結(jié)束線(xiàn)程當(dāng)一個(gè)線(xiàn)程從run()方法的結(jié)尾處返回時(shí),它自動(dòng)消亡并且不能再被運(yùn)行,可以將其理解為自然死亡另一種情況是遇到異常使得線(xiàn)程結(jié)束,可以將其理解為強(qiáng)迫死亡還可以使用interrupt()方法中斷線(xiàn)程的執(zhí)行查詢(xún)線(xiàn)程狀態(tài)在程序代碼中,可以利用Thread類(lèi)中的靜態(tài)方法currentThread()來(lái)引用正在運(yùn)行的線(xiàn)程有時(shí)候可能不知道一個(gè)線(xiàn)程的運(yùn)行狀態(tài),這時(shí)可以使用方法isAlive()來(lái)獲取一個(gè)線(xiàn)程是否還在活動(dòng)狀態(tài)的信息活動(dòng)狀態(tài)不意味著這個(gè)線(xiàn)程正在執(zhí)行,而只說(shuō)明這個(gè)線(xiàn)程已被啟動(dòng)掛起線(xiàn)程暫停一個(gè)線(xiàn)程也稱(chēng)為掛起在掛起之后,必須重新喚醒線(xiàn)程進(jìn)入運(yùn)行掛起線(xiàn)程的方法——sleep()方法sleep()用于暫時(shí)停止一個(gè)線(xiàn)程的執(zhí)行掛起喚醒線(xiàn)程不是休眠期滿(mǎn)后就立刻被喚醒,因?yàn)榇藭r(shí)其他線(xiàn)程可能正在執(zhí)行重新調(diào)度只在以下幾種情況下才會(huì)發(fā)生被喚醒的線(xiàn)程具有更高的優(yōu)先級(jí)正在執(zhí)行的線(xiàn)程因?yàn)槠渌虮蛔枞绦蛱幱谥С謺r(shí)間片的系統(tǒng)中掛起線(xiàn)程的方法wait()和notify()/notifyAll()方法wait()方法導(dǎo)致當(dāng)前的線(xiàn)程等待,直到其他線(xiàn)程調(diào)用此對(duì)象的notify()方法或notifyAll()方法,才能喚醒線(xiàn)程join()方法join()將引起現(xiàn)行線(xiàn)程等待,直至方法join()所調(diào)用的線(xiàn)程結(jié)束比如在線(xiàn)程B中調(diào)用了線(xiàn)程A的join()方法,直到線(xiàn)程A執(zhí)行完畢后,才會(huì)繼續(xù)執(zhí)行線(xiàn)程B可以想像成將線(xiàn)程A加入到當(dāng)前線(xiàn)程B中第四節(jié)線(xiàn)程的互斥一些同時(shí)運(yùn)行的線(xiàn)程需要共享數(shù)據(jù)此時(shí),每個(gè)線(xiàn)程就必須要考慮與它一起共享數(shù)據(jù)的其他線(xiàn)程的狀態(tài)與行為,否則的話(huà)就不能保證共享數(shù)據(jù)的一致性,因而也就不能保證程序的正確性棧的示例棧具有“后進(jìn)先出”模式,它使用下標(biāo)值idx表示棧中下一個(gè)放置元素的位置有兩個(gè)獨(dú)立的線(xiàn)程A和B都具有對(duì)這個(gè)類(lèi)的同一個(gè)對(duì)象的引用,線(xiàn)程A負(fù)責(zé)入棧,線(xiàn)程B負(fù)責(zé)出棧要求線(xiàn)程A放入棧中的數(shù)據(jù)都要由線(xiàn)程B讀出,不重不漏假設(shè)此時(shí)棧中已經(jīng)有字符1和2,當(dāng)前線(xiàn)程A要入棧一個(gè)字符3,調(diào)用push(3),執(zhí)行了語(yǔ)句data[idx]=c;后被其他線(xiàn)程搶占了,此時(shí)尚未執(zhí)行idx++語(yǔ)句。故idx指向最后入棧的字符的下標(biāo)data123idx=2^如果此時(shí)線(xiàn)程A馬上被喚醒,可以繼續(xù)修正idx的值,從而完成一次完整的入棧操作如若不然,入棧操作執(zhí)行了一半若恰巧線(xiàn)程B此時(shí)正占有CPU,調(diào)用pop(),執(zhí)行出棧操作,則它返回的字符是2,因?yàn)樗葓?zhí)行idx--語(yǔ)句,idx的值變?yōu)?,返回的是data[1]處的字符,即字符2字符3被漏掉了多線(xiàn)程訪(fǎng)問(wèn)共享數(shù)據(jù)時(shí)通常會(huì)引起問(wèn)題產(chǎn)生這種問(wèn)題的原因是對(duì)共享資源訪(fǎng)問(wèn)的不完整性需要尋找一種機(jī)制來(lái)保證對(duì)共享數(shù)據(jù)操作的完整性這種完整性稱(chēng)為共享數(shù)據(jù)操作的同步共享數(shù)據(jù)叫做條件變量鎖定標(biāo)志可以禁止線(xiàn)程在完成代碼關(guān)鍵部分時(shí)被切換這個(gè)關(guān)鍵代碼部分,對(duì)于線(xiàn)程A就是入棧操作及下標(biāo)值增加這兩個(gè)動(dòng)作,對(duì)于線(xiàn)程B就是下標(biāo)值遞減及出棧操作這兩個(gè)動(dòng)作它們要么一起完成,要么都不執(zhí)行在Java中,提供了一個(gè)特殊的鎖定標(biāo)志來(lái)處理共享數(shù)據(jù)的訪(fǎng)問(wèn)對(duì)象的鎖定標(biāo)志引入“對(duì)象互斥鎖”的概念,也稱(chēng)為監(jiān)視器使用它來(lái)實(shí)現(xiàn)不同線(xiàn)程對(duì)共享數(shù)據(jù)操作的同步“對(duì)象互斥鎖”阻止多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)同一個(gè)條件變量Java可以為每一個(gè)對(duì)象的實(shí)例配有一個(gè)“對(duì)象互斥鎖”實(shí)現(xiàn)“對(duì)象互斥鎖”的方法用關(guān)鍵字synchronized來(lái)聲明一個(gè)方法或一段代碼塊,該方法或代碼塊在執(zhí)行時(shí)會(huì)獲取對(duì)象實(shí)例的內(nèi)置鎖,其他線(xiàn)程必須等待鎖的釋放才能訪(fǎng)問(wèn)該方法或代碼塊中的共享數(shù)據(jù)使用關(guān)鍵字volatile來(lái)聲明一個(gè)共享數(shù)據(jù)(變量)。但是,使用volatile關(guān)鍵字只能保證數(shù)據(jù)的可見(jiàn)性和有序性,無(wú)法實(shí)現(xiàn)對(duì)共享數(shù)據(jù)的原子操作,因此不能完全替代使用synchronized實(shí)現(xiàn)同步鎖定標(biāo)志示例classstack{ intidx=0; chardata[]=newchar[6]; publicvoidpush(charc){ synchronized(this){//增加同步標(biāo)志 data[idx]=c; idx++; } }}鎖定標(biāo)志方法publiccharpop(){ synchronized(this){ //增加同步標(biāo)志 idx--; returndata[idx]; }}synchronized(this)現(xiàn)在pop()和push()操作的部分增加了一個(gè)對(duì)synchronized(this)的調(diào)用,在第一個(gè)線(xiàn)程擁有鎖定標(biāo)記時(shí),如果另一個(gè)線(xiàn)程企圖執(zhí)行synchronized(this)中的語(yǔ)句時(shí),它將從對(duì)象this中索取鎖定標(biāo)記因?yàn)檫@個(gè)標(biāo)記不可得,故該線(xiàn)程不能繼續(xù)執(zhí)行實(shí)際上這個(gè)線(xiàn)程將加入一個(gè)等待隊(duì)列,該等待隊(duì)列與對(duì)象鎖定標(biāo)志相連,當(dāng)標(biāo)志被返還給對(duì)象時(shí),等待標(biāo)志的第一個(gè)線(xiàn)程將得到該標(biāo)志并繼續(xù)運(yùn)行因?yàn)榈却粋€(gè)對(duì)象的鎖定標(biāo)志的線(xiàn)程要等到持有該標(biāo)志的線(xiàn)程將其返還后才能繼續(xù)運(yùn)行,所以在不使用該標(biāo)志時(shí)將其返還就顯得十分重要了事實(shí)上,當(dāng)持有鎖定標(biāo)志的線(xiàn)程運(yùn)行完synchronized()調(diào)用包含的程序塊后,這個(gè)標(biāo)志將會(huì)被自動(dòng)返還如果一個(gè)線(xiàn)程兩次調(diào)用了同一個(gè)對(duì)象,在退出最外層后這個(gè)標(biāo)志也將被正確釋放,而在退出內(nèi)層時(shí)則不會(huì)執(zhí)行釋放用synchronized標(biāo)識(shí)的代碼段或方法即為“對(duì)象互斥鎖”鎖住的部分如果一個(gè)程序內(nèi)有兩個(gè)或以上的方法使用synchronized標(biāo)志,則它們?cè)谕粋€(gè)“對(duì)象互斥鎖”管理之下synchronized()語(yǔ)句publicvoidpush(charc){ synchronized(this){

┊ }}或是publicsynchronizedvoidpush(charc){

┊}第五節(jié)線(xiàn)程的同步為了完成多個(gè)任務(wù),常創(chuàng)建多個(gè)線(xiàn)程,它們可能毫不相關(guān),但有時(shí)它們完成的任務(wù)在某種程度上有一定的關(guān)系,此時(shí)就需要線(xiàn)程之間有一些交互使用方法wait()和notify()/notifyall()實(shí)現(xiàn)線(xiàn)程的交互操作系統(tǒng)中的生產(chǎn)者消費(fèi)者問(wèn)題,就是一個(gè)經(jīng)典的同步問(wèn)題若共享對(duì)象中只能存放一個(gè)數(shù)據(jù),可能出現(xiàn)以下問(wèn)題:生產(chǎn)者比消費(fèi)者快時(shí),消費(fèi)者會(huì)漏掉一些數(shù)據(jù)沒(méi)有取到消費(fèi)者比生產(chǎn)者快時(shí),消費(fèi)者取相同的數(shù)據(jù)解決方法Java中的每個(gè)對(duì)象實(shí)例都有兩個(gè)線(xiàn)程隊(duì)列和它相連第一個(gè)用來(lái)排列等待鎖定標(biāo)志的線(xiàn)程第二個(gè)則用來(lái)實(shí)現(xiàn)wait()和notify()的交互機(jī)制類(lèi)java.lang.Object中定義了三個(gè)方法wait()notify()notifyAll()wait()方法導(dǎo)致當(dāng)前的線(xiàn)程等待,它的作用是讓當(dāng)前線(xiàn)程釋放其所持有的“對(duì)象互斥鎖”,進(jìn)入wait隊(duì)列(等待隊(duì)列)notify()/notifyAll()方法的作用是喚醒一個(gè)或所有正在等待隊(duì)列中等待的線(xiàn)程,并將它(們)移入等待同一個(gè)“對(duì)象互斥鎖”的隊(duì)列notify()/notifyAll()方法和wait()方法都只能在被聲明為synchronized的方法或代碼段中調(diào)用方法

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論