摘要:本人郵箱歡迎轉載轉載請注明網址代碼已經全部托管有需要的同學自行下載引言在寫五多線程之類時我們暫時忽略掉的一個方法那就是這個方法返回一個現在我們這章就重點講這個東東是什么以及怎么使用理論的中文翻譯是狀態沒錯這個就是讓多線程在不同狀態切換其他線
引言本人郵箱:
歡迎轉載,轉載請注明網址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代碼已經全部托管github有需要的同學自行下載
在寫(五)java多線程之Lock類時,我們暫時忽略掉Lock的一個方法,那就是Lock.newCondition(),這個方法返回一個Condition,現在我們這章就重點講這個東東是什么,以及怎么使用.
理論Condition的中文翻譯是狀態.沒錯,這個就是讓多線程在不同狀態切換其他線程執行.跟Object.wait和Object.notify有點類似.
Condition.await: 讓當前線程一直等到直到獲取信號,或者發生中斷.通過和lock鎖互相配合,會使當前線程一直睡眠直到一下四種情況的其中一種發生:
另外一個線程調用當前Condition的signal方法,這當前線程會被挑選出來,并被喚醒
其他線程調用了當前Condition的signalAll方法
其他線程調用了當前線程的中斷,這當前中斷會被掛起
當前線程被假喚醒
Condition.awaitUninterruptibly 跟Condition.await類似,只是不能被中斷
Condition.await(long time, TimeUnit unit) 當前線程會被喚醒,要么是獲得信號,要么是中斷,要么是指定時間到
Condition.awaitUntil(Date deadline)當前線程會被喚醒,要么是獲得信號,要么是中斷,要么是到了指定結束時間
一般用法如下
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 喚醒等待的線程.如果當前的condition有多個線程在等待的話,這會喚醒其中一,且這個線程在返回await前必須重新獲得鎖
"Condition.signalAll" 喚醒所有等待的線程.如果當前的condition有多個線程在等待,則所有的線程都會被喚醒,且這些被喚醒的線程必須在返回await之前重新獲得鎖
例子1枯燥無聊的理論,看完之后就忘記,還是要寫一個例子加深印象吧.這里我們還是用之前小明和小紅談人生,談理想的例子繼續說明吧
首先要中間人GrilProduct,花花公子PlayBoy和測試類TestMain,都是跟之前(三)java多線程之wait notify notifyAlljava多線程之wait notify notifyAll,md)一樣,這里就不占用篇幅了
我們繼續改寫臥室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 + " 我的心在等待... 永遠在等待.. " ); 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 + " 我的心在等待... 永遠在等待.. " ); 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(); } } }
運行一下,結果如下
小紅1號 我的心在等待... 永遠在等待.. 小明0號 play with 小紅0號 小明9號 我的心在等待... 永遠在等待.. 小明2號 我的心在等待... 永遠在等待.. 小明5號 我的心在等待... 永遠在等待.. 小明7號 我的心在等待... 永遠在等待.. 小明4號 我的心在等待... 永遠在等待.. 小明6號 我的心在等待... 永遠在等待.. 小明1號 我的心在等待... 永遠在等待.. 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅2號 我的心在等待... 永遠在等待.. 小明9號 play with 小紅1號 小明2號 我的心在等待... 永遠在等待.. 小明5號 我的心在等待... 永遠在等待.. 小明7號 我的心在等待... 永遠在等待.. 小明4號 我的心在等待... 永遠在等待.. 小明6號 我的心在等待... 永遠在等待.. 小明1號 我的心在等待... 永遠在等待.. 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅3號 我的心在等待... 永遠在等待.. 小明2號 play with 小紅2號 小明5號 我的心在等待... 永遠在等待.. 小明7號 我的心在等待... 永遠在等待.. 小明4號 我的心在等待... 永遠在等待.. 小明6號 我的心在等待... 永遠在等待.. 小明1號 我的心在等待... 永遠在等待.. 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅4號 我的心在等待... 永遠在等待.. 小明5號 play with 小紅3號 小明7號 我的心在等待... 永遠在等待.. 小明4號 我的心在等待... 永遠在等待.. 小明6號 我的心在等待... 永遠在等待.. 小明1號 我的心在等待... 永遠在等待.. 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅5號 我的心在等待... 永遠在等待.. 小明7號 play with 小紅4號 小明4號 我的心在等待... 永遠在等待.. 小明6號 我的心在等待... 永遠在等待.. 小明1號 我的心在等待... 永遠在等待.. 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅6號 我的心在等待... 永遠在等待.. 小明4號 play with 小紅5號 小明6號 我的心在等待... 永遠在等待.. 小明1號 我的心在等待... 永遠在等待.. 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅7號 我的心在等待... 永遠在等待.. 小明6號 play with 小紅6號 小明1號 我的心在等待... 永遠在等待.. 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅8號 我的心在等待... 永遠在等待.. 小明1號 play with 小紅7號 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅9號 我的心在等待... 永遠在等待.. 小明3號 play with 小紅8號 小明8號 我的心在等待... 永遠在等待.. 小明8號 play with 小紅9號
跟之前的結果差不多.
例子2這時候就有人質疑了,既然結果跟用Object.wait和Object.notify一樣,那為什么要用這個呢?細心的讀者可以發現了,每次運行,同一個小明可能和不同的小紅談人生和理想.這時候小明是很開心.但小紅卻不樂意,覺得小明太花心,太不專一,什么甜言蜜語都是騙人的.好,那我們現在就讓小明專一.幫小紅排除他們的煩惱.
這時候全部的類都要改造了,沒辦法小紅太強勢了
首先我們改造一下中間人GrilProduct,讓每一個小紅都自帶編號進入臥室等候
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 + "號", i); } } }
之后我們改造花花公子,他們進入房間時,要拿著小紅對應的編號進入
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了 ,讓小紅和小明的號碼對應上,才讓他們談人生和理想,不然就讓他們繼續等待..
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 + " 我的心在等待... 永遠在等待.. " ); 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 + " 我的心在等待... 永遠在等待.. " ); 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(); } } }
最后改寫我們的測試類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 + "號", i))); } grilProduct.start(); for (Thread boy : boyThread){ boy.start(); } } }
運行一下,結果如下:
小紅1號 我的心在等待... 永遠在等待.. 小明9號 我的心在等待... 永遠在等待.. 小明0號 play with 小紅0號 小明2號 我的心在等待... 永遠在等待.. 小明5號 我的心在等待... 永遠在等待.. 小明7號 我的心在等待... 永遠在等待.. 小明4號 我的心在等待... 永遠在等待.. 小明6號 我的心在等待... 永遠在等待.. 小明1號 我的心在等待... 永遠在等待.. 小明3號 我的心在等待... 永遠在等待.. 小明8號 我的心在等待... 永遠在等待.. 小紅2號 我的心在等待... 永遠在等待.. 小明1號 play with 小紅1號 小紅3號 我的心在等待... 永遠在等待.. 小明2號 play with 小紅2號 小紅4號 我的心在等待... 永遠在等待.. 小明3號 play with 小紅3號 小紅5號 我的心在等待... 永遠在等待.. 小明4號 play with 小紅4號 小紅6號 我的心在等待... 永遠在等待.. 小明5號 play with 小紅5號 小紅7號 我的心在等待... 永遠在等待.. 小明6號 play with 小紅6號 小紅8號 我的心在等待... 永遠在等待.. 小明7號 play with 小紅7號 小紅9號 我的心在等待... 永遠在等待.. 小明8號 play with 小紅8號 小明9號 play with 小紅9號
恩小明和小紅終于配對了,媽媽再也不用我被小紅們追著打了,不過,小明們,我就對不住你們了.~~
如果覺得我的文章寫的還過得去的話,有錢就捧個錢場,沒錢給我捧個人場(幫我點贊或推薦一下)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69903.html
摘要:開始獲取鎖終于輪到出場了,的調用過程和完全一樣,同樣拿不到鎖,然后加入到等待隊列隊尾然后,在阻塞前需要把前驅結點的狀態置為,以確保將來可以被喚醒至此,的執行也暫告一段落了安心得在等待隊列中睡覺。 showImg(https://segmentfault.com/img/remote/1460000016012467); 本文首發于一世流云的專欄:https://segmentfault...
摘要:公平策略在多個線程爭用鎖的情況下,公平策略傾向于將訪問權授予等待時間最長的線程。使用方式的典型調用方式如下二類原理的源碼非常簡單,它通過內部類實現了框架,接口的實現僅僅是對的的簡單封裝,參見原理多線程進階七鎖框架獨占功能剖析 showImg(https://segmentfault.com/img/remote/1460000016012582); 本文首發于一世流云的專欄:https...
摘要:返回與此鎖相關聯的給定條件等待的線程數的估計。查詢是否有線程正在等待獲取此鎖。為公平鎖,為非公平鎖線程運行了獲得鎖定運行結果公平鎖的運行結果是有序的。 系列文章傳送門: Java多線程學習(一)Java多線程入門 Java多線程學習(二)synchronized關鍵字(1) java多線程學習(二)synchronized關鍵字(2) Java多線程學習(三)volatile關鍵字 ...
摘要:關于接口的介紹,可以參見多線程進階二鎖框架接口。最終線程釋放了鎖,并進入阻塞狀態。當線程被通知喚醒時,則是將條件隊列中的結點轉換成等待隊列中的結點,之后的處理就和獨占功能完全一樣。 showImg(https://segmentfault.com/img/remote/1460000016012490); 本文首發于一世流云的專欄:https://segmentfault.com/bl...
摘要:中具有通過實現的內置鎖,和實現的顯示鎖,這兩種鎖各有各的好處,算是互有補充,今天就來做一個總結。內置鎖獲得鎖和釋放鎖是隱式的,進入修飾的代碼就獲得鎖,走出相應的代碼就釋放鎖。是顯示鎖,需要顯示進行以及操作。 Java中具有通過Synchronized實現的內置鎖,和ReentrantLock實現的顯示鎖,這兩種鎖各有各的好處,算是互有補充,今天就來做一個總結。 Synchronized...
閱讀 3639·2021-11-24 09:38
閱讀 3142·2021-11-15 11:37
閱讀 781·2021-11-12 10:36
閱讀 3547·2021-10-21 09:38
閱讀 3220·2021-09-28 09:36
閱讀 2420·2021-09-22 16:01
閱讀 4986·2021-09-22 15:09
閱讀 1210·2019-08-30 15:55