摘要:本人郵箱歡迎轉(zhuǎn)載轉(zhuǎn)載請(qǐng)注明網(wǎng)址代碼已經(jīng)全部托管有需要的同學(xué)自行下載引言在寫五多線程之類時(shí)我們暫時(shí)忽略掉的一個(gè)方法那就是這個(gè)方法返回一個(gè)現(xiàn)在我們這章就重點(diǎn)講這個(gè)東東是什么以及怎么使用理論的中文翻譯是狀態(tài)沒錯(cuò)這個(gè)就是讓多線程在不同狀態(tài)切換其他線
引言本人郵箱:
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明網(wǎng)址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代碼已經(jīng)全部托管github有需要的同學(xué)自行下載
在寫(五)java多線程之Lock類時(shí),我們暫時(shí)忽略掉Lock的一個(gè)方法,那就是Lock.newCondition(),這個(gè)方法返回一個(gè)Condition,現(xiàn)在我們這章就重點(diǎn)講這個(gè)東東是什么,以及怎么使用.
理論Condition的中文翻譯是狀態(tài).沒錯(cuò),這個(gè)就是讓多線程在不同狀態(tài)切換其他線程執(zhí)行.跟Object.wait和Object.notify有點(diǎn)類似.
Condition.await: 讓當(dāng)前線程一直等到直到獲取信號(hào),或者發(fā)生中斷.通過和lock鎖互相配合,會(huì)使當(dāng)前線程一直睡眠直到一下四種情況的其中一種發(fā)生:
另外一個(gè)線程調(diào)用當(dāng)前Condition的signal方法,這當(dāng)前線程會(huì)被挑選出來,并被喚醒
其他線程調(diào)用了當(dāng)前Condition的signalAll方法
其他線程調(diào)用了當(dāng)前線程的中斷,這當(dāng)前中斷會(huì)被掛起
當(dāng)前線程被假喚醒
Condition.awaitUninterruptibly 跟Condition.await類似,只是不能被中斷
Condition.await(long time, TimeUnit unit) 當(dāng)前線程會(huì)被喚醒,要么是獲得信號(hào),要么是中斷,要么是指定時(shí)間到
Condition.awaitUntil(Date deadline)當(dāng)前線程會(huì)被喚醒,要么是獲得信號(hào),要么是中斷,要么是到了指定結(jié)束時(shí)間
一般用法如下
boolean aMethod(Date deadline) { boolean stillWaiting = true; lock.lock(); try { while (!conditionBeingWaitedFor()) { if (!stillWaiting) return false; stillWaiting = theCondition.awaitUntil(deadline); } // ... } finally { lock.unlock(); } }
Condition.signal 喚醒等待的線程.如果當(dāng)前的condition有多個(gè)線程在等待的話,這會(huì)喚醒其中一,且這個(gè)線程在返回await前必須重新獲得鎖
"Condition.signalAll" 喚醒所有等待的線程.如果當(dāng)前的condition有多個(gè)線程在等待,則所有的線程都會(huì)被喚醒,且這些被喚醒的線程必須在返回await之前重新獲得鎖
例子1枯燥無聊的理論,看完之后就忘記,還是要寫一個(gè)例子加深印象吧.這里我們還是用之前小明和小紅談人生,談理想的例子繼續(xù)說明吧
首先要中間人GrilProduct,花花公子PlayBoy和測(cè)試類TestMain,都是跟之前(三)java多線程之wait notify notifyAlljava多線程之wait notify notifyAll,md)一樣,這里就不占用篇幅了
我們繼續(xù)改寫臥室Room類
public class Room { Lock lock = new ReentrantLock(); Condition boyIsCome = lock.newCondition(); Condition girlIsCome = lock.newCondition(); private String gril = null; public void makeGridInRoom(String gril){ lock.lock(); try { while (this.gril != null){ System.out.println(gril + " 我的心在等待... 永遠(yuǎn)在等待.. " ); girlIsCome.await(); } Thread.sleep(10); this.gril = gril; boyIsCome.signalAll(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public void playWithGril(String boy){ lock.lock(); try { while (this.gril == null){ System.out.println(boy + " 我的心在等待... 永遠(yuǎn)在等待.. " ); boyIsCome.await(); } Thread.sleep(10); System.out.println(boy + " play with " + this.gril); Thread.sleep(500); this.gril = null; girlIsCome.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }
運(yùn)行一下,結(jié)果如下
小紅1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明0號(hào) play with 小紅0號(hào) 小明9號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明2號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明5號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明7號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明4號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅2號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明9號(hào) play with 小紅1號(hào) 小明2號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明5號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明7號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明4號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明2號(hào) play with 小紅2號(hào) 小明5號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明7號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明4號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅4號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明5號(hào) play with 小紅3號(hào) 小明7號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明4號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅5號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明7號(hào) play with 小紅4號(hào) 小明4號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明4號(hào) play with 小紅5號(hào) 小明6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅7號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明6號(hào) play with 小紅6號(hào) 小明1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) play with 小紅7號(hào) 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅9號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) play with 小紅8號(hào) 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) play with 小紅9號(hào)
跟之前的結(jié)果差不多.
例子2這時(shí)候就有人質(zhì)疑了,既然結(jié)果跟用Object.wait和Object.notify一樣,那為什么要用這個(gè)呢?細(xì)心的讀者可以發(fā)現(xiàn)了,每次運(yùn)行,同一個(gè)小明可能和不同的小紅談人生和理想.這時(shí)候小明是很開心.但小紅卻不樂意,覺得小明太花心,太不專一,什么甜言蜜語都是騙人的.好,那我們現(xiàn)在就讓小明專一.幫小紅排除他們的煩惱.
這時(shí)候全部的類都要改造了,沒辦法小紅太強(qiáng)勢(shì)了
首先我們改造一下中間人GrilProduct,讓每一個(gè)小紅都自帶編號(hào)進(jìn)入臥室等候
public class GrilProduct implements Runnable{ private Room room; public GrilProduct(Room room) { this.room = room; } @Override public void run() { for (int i = 0; i < 10; i ++){ room.makeGridInRoom("小紅" + i + "號(hào)", i); } } }
之后我們改造花花公子,他們進(jìn)入房間時(shí),要拿著小紅對(duì)應(yīng)的編號(hào)進(jìn)入
public class PlayBoy implements Runnable{ private Room room; private String boy; private int index; public PlayBoy(Room room, String boy, int index) { this.room = room; this.boy = boy; this.index = index; } @Override public void run() { room.playWithGril(boy, index); } }
之后就是要改寫臥室類Room了 ,讓小紅和小明的號(hào)碼對(duì)應(yīng)上,才讓他們談人生和理想,不然就讓他們繼續(xù)等待..
public class Room { Lock lock; ListboyIsCome; Condition girlIsCome; private String gril = null; private int index = -1; public Room(){ lock = new ReentrantLock(); girlIsCome = lock.newCondition(); boyIsCome = new ArrayList<>(); for (int i = 0; i < 10; i ++){ boyIsCome.add(lock.newCondition()); } } public void makeGridInRoom(String gril, int index){ lock.lock(); try { while (this.gril != null){ System.out.println(gril + " 我的心在等待... 永遠(yuǎn)在等待.. " ); girlIsCome.await(); } Thread.sleep(10); this.gril = gril; this.index = index; boyIsCome.get(index).signal(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public void playWithGril(String boy, int index){ lock.lock(); try { while (this.gril == null || this.index != index){ System.out.println(boy + " 我的心在等待... 永遠(yuǎn)在等待.. " ); boyIsCome.get(index).await(); } Thread.sleep(10); System.out.println(boy + " play with " + this.gril); Thread.sleep(500); this.gril = null; this.index = -1; girlIsCome.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }
最后改寫我們的測(cè)試類TestMain
public class TestMain { public static void main(String[] args) { Room room = new Room(); Thread grilProduct = new Thread(new GrilProduct(room)); SetboyThread = new HashSet<>(); for (int i = 0; i < 10; i ++){ boyThread.add(new Thread(new PlayBoy(room, "小明" + i + "號(hào)", i))); } grilProduct.start(); for (Thread boy : boyThread){ boy.start(); } } }
運(yùn)行一下,結(jié)果如下:
小紅1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明9號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明0號(hào) play with 小紅0號(hào) 小明2號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明5號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明7號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明4號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小紅2號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明1號(hào) play with 小紅1號(hào) 小紅3號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明2號(hào) play with 小紅2號(hào) 小紅4號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明3號(hào) play with 小紅3號(hào) 小紅5號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明4號(hào) play with 小紅4號(hào) 小紅6號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明5號(hào) play with 小紅5號(hào) 小紅7號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明6號(hào) play with 小紅6號(hào) 小紅8號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明7號(hào) play with 小紅7號(hào) 小紅9號(hào) 我的心在等待... 永遠(yuǎn)在等待.. 小明8號(hào) play with 小紅8號(hào) 小明9號(hào) play with 小紅9號(hào)
恩小明和小紅終于配對(duì)了,媽媽再也不用我被小紅們追著打了,不過,小明們,我就對(duì)不住你們了.~~
如果覺得我的文章寫的還過得去的話,有錢就捧個(gè)錢場(chǎng),沒錢給我捧個(gè)人場(chǎng)(幫我點(diǎn)贊或推薦一下)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69903.html
摘要:開始獲取鎖終于輪到出場(chǎng)了,的調(diào)用過程和完全一樣,同樣拿不到鎖,然后加入到等待隊(duì)列隊(duì)尾然后,在阻塞前需要把前驅(qū)結(jié)點(diǎn)的狀態(tài)置為,以確保將來可以被喚醒至此,的執(zhí)行也暫告一段落了安心得在等待隊(duì)列中睡覺。 showImg(https://segmentfault.com/img/remote/1460000016012467); 本文首發(fā)于一世流云的專欄:https://segmentfault...
摘要:公平策略在多個(gè)線程爭(zhēng)用鎖的情況下,公平策略傾向于將訪問權(quán)授予等待時(shí)間最長(zhǎng)的線程。使用方式的典型調(diào)用方式如下二類原理的源碼非常簡(jiǎn)單,它通過內(nèi)部類實(shí)現(xiàn)了框架,接口的實(shí)現(xiàn)僅僅是對(duì)的的簡(jiǎn)單封裝,參見原理多線程進(jìn)階七鎖框架獨(dú)占功能剖析 showImg(https://segmentfault.com/img/remote/1460000016012582); 本文首發(fā)于一世流云的專欄:https...
摘要:返回與此鎖相關(guān)聯(lián)的給定條件等待的線程數(shù)的估計(jì)。查詢是否有線程正在等待獲取此鎖。為公平鎖,為非公平鎖線程運(yùn)行了獲得鎖定運(yùn)行結(jié)果公平鎖的運(yùn)行結(jié)果是有序的。 系列文章傳送門: Java多線程學(xué)習(xí)(一)Java多線程入門 Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(2) Java多線程學(xué)習(xí)(三)volatile關(guān)鍵字 ...
摘要:關(guān)于接口的介紹,可以參見多線程進(jìn)階二鎖框架接口。最終線程釋放了鎖,并進(jìn)入阻塞狀態(tài)。當(dāng)線程被通知喚醒時(shí),則是將條件隊(duì)列中的結(jié)點(diǎn)轉(zhuǎn)換成等待隊(duì)列中的結(jié)點(diǎn),之后的處理就和獨(dú)占功能完全一樣。 showImg(https://segmentfault.com/img/remote/1460000016012490); 本文首發(fā)于一世流云的專欄:https://segmentfault.com/bl...
摘要:中具有通過實(shí)現(xiàn)的內(nèi)置鎖,和實(shí)現(xiàn)的顯示鎖,這兩種鎖各有各的好處,算是互有補(bǔ)充,今天就來做一個(gè)總結(jié)。內(nèi)置鎖獲得鎖和釋放鎖是隱式的,進(jìn)入修飾的代碼就獲得鎖,走出相應(yīng)的代碼就釋放鎖。是顯示鎖,需要顯示進(jìn)行以及操作。 Java中具有通過Synchronized實(shí)現(xiàn)的內(nèi)置鎖,和ReentrantLock實(shí)現(xiàn)的顯示鎖,這兩種鎖各有各的好處,算是互有補(bǔ)充,今天就來做一個(gè)總結(jié)。 Synchronized...
閱讀 3679·2021-11-24 09:38
閱讀 3159·2021-11-15 11:37
閱讀 799·2021-11-12 10:36
閱讀 3557·2021-10-21 09:38
閱讀 3230·2021-09-28 09:36
閱讀 2430·2021-09-22 16:01
閱讀 5005·2021-09-22 15:09
閱讀 1230·2019-08-30 15:55