版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、1. 線程的掛起和喚醒掛起實際上是讓線程進入“非可執(zhí)行”狀態(tài)下,在這個狀態(tài)下CPU不會分給線程時間片,進入這個狀態(tài)可以用來暫停一個線程的運行;在線程掛起后, 可以通過重新喚醒線程來使之恢復(fù)運行。掛起的原因可能是如下幾種情況:( 1)通過調(diào)用 sleep() 方法使線程進入休眠狀態(tài),線程在指定時間內(nèi)不會運行。( 2)通過調(diào)用 join() 方法使線程掛起,使自己等待另一個線程的結(jié)果,直到另一個線程執(zhí)行完畢為止。(3)通過調(diào)用wait()方法使線程掛起,直到線程得到了notify()和 notifyAll()消息,線程才會進入“可執(zhí)行”狀態(tài)。(4)使用 suspend 掛起線程后,可以通過resu
2、me 方法喚醒線程。雖然 suspend 和 resume 可以很方便地使線程掛起和喚醒,但由于使用這兩個方法可能會造成死鎖,因此,這兩個方法被標(biāo)識為deprecated (抗議)標(biāo)記,這表明在以后的jdk版本中這兩個方法可能被刪除,所以盡量不要使用這兩個方法來操作線程。調(diào)用 sleep() 、 yield() 、 suspend() 的時候并沒有被釋放鎖調(diào)用 wait() 的時候釋放當(dāng)前對象的鎖wait()方法表示, 放棄當(dāng)前對資源的占有權(quán),一直等到有線程通知,才會運行后面的代碼。notify()方法表示, 當(dāng)前的線程已經(jīng)放棄對資源的占有,通知等待的線程來獲得對資源的占有權(quán),但是只有一個線程
3、能夠從wait 狀態(tài)中恢復(fù),然后繼續(xù)運行wait()后面的語句。notifyAll()方法表示,當(dāng)前的線程已經(jīng)放棄對資源的占有,通知所有的等待線程從wait()方法后的語句開始運行。2. 等待和鎖實現(xiàn)資源競爭1.2.3.4.5.6.1.2.3.4.等待機制與鎖機制是密切關(guān)聯(lián)的,對于需要競爭的資源,首先用synchronized確保這段代碼只能一個線程執(zhí)行,可以再設(shè)置一個標(biāo)志位condition判斷該資源是否準(zhǔn)備好,如果沒有,則該線程釋放鎖,自己進入等待狀態(tài),直到接收到notify,程序從 wait處繼續(xù)向下執(zhí)行。synchronized( obj )while(! condition)obj.
4、 wait();obj . doSomething();以上程序表示只有一個線程A 獲得了 obj 鎖后,發(fā)現(xiàn)條件 condition不滿足, 無法繼續(xù)下一處理,于是線程A 釋放該鎖,進入wait()。在另一線程B 中,如果 B 更改了某些條件,使得線程A 的 condition條件滿足了, 就可以喚醒線程A:synchronized( obj )condition= true;obj . notify();需要注意的是:# 調(diào)用obj的wait(), notify()方法前,必須獲得obj鎖,也就是必須寫在synchronized(obj) .代碼段內(nèi)。# 調(diào)用 obj.wait()后,線程
5、A 就釋放了obj 的鎖,否則線程B 無法獲得obj 鎖,也就無法在 synchronized(obj) .代碼段內(nèi)喚醒A。# 當(dāng) obj.wait()方法返回后,線程A 需要再次獲得obj 鎖,才能繼續(xù)執(zhí)行。#如果 A1,A2,A3 都在 obj.wait(),則 B 調(diào)用 obj.notify()只能喚醒 A1,A2,A3 中的一個( 具體哪一個由JVM決定 ) 。# obj.notifyAll()則能全部喚醒A1,A2,A3 ,但是要繼續(xù)執(zhí)行obj.wait()的下一條語句,必須獲得obj 鎖,因此, A1,A2,A3 只有一個有機會獲得鎖繼續(xù)執(zhí)行,例如A1,其余的需要等待 A1 釋放
6、obj 鎖之后才能繼續(xù)執(zhí)行。# 當(dāng) B 調(diào)用 obj.notify/notifyAll的時候, B 正持有 obj 鎖,因此, A1,A2,A3 雖被喚醒,但是仍無法獲得obj 鎖。直到 B 退出 synchronized塊,釋放 obj 鎖后, A1,A2,A3 中的一個才有機會獲得鎖繼續(xù)執(zhí)行。例 1:單個線程對多個線程的喚醒假設(shè)只有一個 Game對象,但有 3 個人要玩,由于只有一個游戲資源,必須必然依次玩。1./*2.* 玩游戲的人 .3.* version V1.0 ,2011-4-84.* author xiahui5.*/6.public classPlayerimplements
7、Runnable7.privatefinalintid ;8.privateGame game ;9.10.public Player( intid ,Game game )11.this. id=id ;12.this. game= game ;13.14.15.16.publicStringtoString()17.returnAthlete;18.19.20.publicinthashCode ()21.returnnew Integer( id ). hashCode();22.23.24.publicvoidplayGame ()throwsInterruptedException2
8、5.System . out . println( this. toString() + ready!);26.game. play( this);27.28.29.publicvoidrun ()30.try31.playGame();32. catch( InterruptedExceptione )33.System . out . println( this+ quit the game);34.35.36.游戲類,只實例化一個1.importjava. util. HashSet ;2.importjava. util. Iterator;3.importjava. util. Se
9、t ;4.5./*6.* 游戲類.7.* version V1.0 ,2011-4-88.* author xiahui9.*/10.publicclassGame implementsRunnable11.privatebooleanstart= false;12.13.publicvoidplay( Player player)throwsInterruptedException14.synchronized( this)15.while(!start)16.wait();17.if( start)18.System . out . println( player+ have played
10、!);19.20.21.22./通知所有玩家23.publicsynchronizedvoidbeginStart()24.start= true;25.notifyAll();26.27.28.publicvoidrun ()29.start= false;30.System . out . println( Ready.);31.System . out . println( Ready.);32.System . out . println( game start);33.beginStart();/ 通知所有玩家游戲準(zhǔn)備好了34.35.36.37.38.39.40.41.42.43.4
11、4.45.46.47.48.49.50.51.52.53.54.publicstaticvoidmain ( Stringargs)Set players= new HashSet ();/ 實例化一個游戲Game game= new Game ();/ 實例化 3 個玩家for( inti= 0 ; i 3 ; i +)players. add ( new Player( i , game );/ 啟動 3 個玩家Iterator iter= players. iterator();while( iter. hasNext ()new Thread ( iter. next ().start
12、();Thread.sleep( 100);/ 游戲啟動new Thread ( game). start();程序先啟動玩家,三個玩家競爭玩游戲,但只能有一個進入play ,其他二個等待,進入的玩家發(fā)現(xiàn)游戲未準(zhǔn)備好,所以wait ,等游戲準(zhǔn)備好后,依次玩。運行結(jié)果1.Athlete ready!2.Athlete ready!3.Athlete ready!4.Ready.5.Ready.6.game start7.Athlete have played!8.Athlete have played!9.Athlete have played!3. 一次喚醒一個線程一次喚醒所有玩家,但只有一個
13、玩家能玩,不如一個一個喚醒將上面的代碼修改如下publicvoidplay ( Player player)throwsInterruptedExceptionsynchronized( this)while(! start)wait ();if( start)System . out . println( player+ have played!);notify();/ 玩完后,通知下一個玩家來玩/ 通知一個玩家publicsynchronizedvoidbeginStart()start= true;notify();4.suspend 掛起該方法已不建議使用,例子如下例 2:suspen
14、d 方法進行掛起和喚醒1./*2.* suspend方法進行掛起和喚醒 .3.* version V1.0 ,2011-3-274.* author xiahui5.*/6.public class SuspendThreadimplementsRunnable 7.publicvoidrun ()8.try9.Thread . sleep ( 10);10.catch( Exceptione )11.System . out . println( e );12.13.for( inti= 0 ; i= 1 ; i )14.System . out . println( Thread . cu
15、rrentThread().getName () : i );15.16.17.18.publicstaticvoidmain ( Stringargs)throwsException19.Threadth1=newThread ( new SuspendThread(),thread1);20.Threadth2=newThread ( new SuspendThread(),thread2);21.System . out . println( Starting th1 . getName (). );22.th1. start();23.System . out . println( S
16、uspending th1. getName ().);24./Suspend the thread.25.th1. suspend();26.th2. start();27.th2. join();28./ Resume the thread.29.th1. resume ();30.31.運行結(jié)果1.Starting thread1.2.3.4.5.6.注意:Suspending thread1.thread2: 0thread2: 1thread1: 0thread1: 1如果注釋掉 /th2.join(); 則 thread2 運行后,主線程會直接執(zhí)行 thread1 的 resume
17、,運行結(jié)果可能會是1.2.3.4.5.6.Starting thread1.Suspending thread1.thread1: 0thread1: 1thread2: 0thread2: 11、 synchronized關(guān)鍵字的作用域有二種:1)是某個對象實例內(nèi),synchronized aMethod()可以防止多個線程同時訪問這個對象的synchronized方法(如果一個對象有多個synchronized方法,只要一個線程訪問了其中的一個 synchronized方法,其它線程不能同時訪問這個對象中任何一個synchronized 方法)。這時,不同的對象實例的synchronize
18、d方法是不相干擾的。也就是說,其它線程照樣可以同時訪問相同類的另一個對象實例中的synchronized 方法;2)是某個類的范圍, synchronized static aStaticMethod防止多個線程同時訪問這個類中的 synchronized static方法。它可以對類的所有對象實例起作用。2、除了方法前用synchronized關(guān)鍵字, synchronized關(guān)鍵字還可以用于方法中的某個區(qū)塊中,表示只對這個區(qū)塊的資源實行互斥訪問。用法是: synchronized(this)/*區(qū)塊 */ ,它的作用域是當(dāng)前對象;3、 synchronized關(guān)鍵字是不能繼承的,也就是說,基類的方法synchronized f()在繼承類中并不自動是synchronizedf(),而是變成了 f()。繼承類需要你顯式的指定它的某個方法為 synchronized方法;/* synchronized用法* */publicclass SyncThreadextendsThreadprivateintval;publicSyncThread(intv)val = v;/ 同步加鎖的是對象,而不是代碼
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度個人房屋抵押民間借貸借款協(xié)議文本3篇
- 2025年度平板車租賃運輸合同風(fēng)險評估與控制
- 個人租房合同標(biāo)準(zhǔn)版可打印
- 二零二五年度處理男子外遇妻子懷孕離婚撫養(yǎng)權(quán)糾紛調(diào)解合同
- 二零二五年度智慧家居項目報建代理與智能家居合同2篇
- 2025年度鐵礦石進出口關(guān)稅及稅費繳納合同規(guī)范
- 二零二五版礦產(chǎn)資源租賃居間代理合同3篇
- 二零二五年度企事業(yè)單位廉潔從業(yè)監(jiān)督員聘任合同
- 2025阿里巴巴智能物流機器人研發(fā)及銷售合同3篇
- 2025年度供應(yīng)鏈金融投資擔(dān)保協(xié)議
- 《大學(xué)生職業(yè)發(fā)展與就業(yè)指導(dǎo)》課程標(biāo)準(zhǔn)
- 第23課《出師表》課件(共56張)
- GB/T 3953-2024電工圓銅線
- 發(fā)電機停電故障應(yīng)急預(yù)案
- 接電的施工方案
- 常用藥物作用及副作用課件
- 幼兒阿拉伯?dāng)?shù)字描紅(0-100)打印版
- 社會組織等級評估報告模板
- GB/T 12173-2008礦用一般型電氣設(shè)備
- 新媒體研究方法教學(xué)ppt課件(完整版)
- 2020新版?zhèn)€人征信報告模板
評論
0/150
提交評論