日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java并发与锁设计实现详述 - Java中的Condition

發布時間:2023/12/20 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java并发与锁设计实现详述 - Java中的Condition 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

關于等待通知機制,在Java中主要有兩種方式。一種是基于wait/notify方法集合synchronized關鍵字實現的,這在上一篇文章《Java并發與鎖設計實現詳述(10)- Java中的等待/通知機制》中已經講述了,另一種方法是Condition結合Lock來實現。

下面先把這兩種方式進行一個簡單的對比。

Object的監控器方法和Condition接口的對比對比項
Object Monitor Methods
Condition
前置條件
在使用之前獲取對象的鎖

調用Lock.lock獲取鎖;

調用Lock.newCondition獲取Condition對象;

調用方式

直接調用,如:object.wait()

直接調用,如condition.await()

等待隊列個數
一個
多個
當前線程釋放鎖并進入等待狀態
支持
支持

當前線程釋放鎖并進入等待狀態,

在等待狀態不響應中斷

不支持
支持
當前線程釋放鎖并進入超時等待狀態
支持
支持

當前線程釋放鎖并進入超時等待狀態,

在超時等待狀態不響應中斷

不支持
支持
喚醒等待隊列中的一個線程
支持
支持
喚醒等待隊列中的全部線程
支持
支持

從上面的對比來看,兩種方式功能基本一樣,只是在響應中斷的場景下有細微區別。

由于前文已經講過基于Object Monitor Methods實現的等待通知機制,在本文將講述另一種實現,即基于Condition接口的實現方式。

Condition的接口與示例

Condition接口定義了等待/通知兩種類型的方法,在線程調用這些方法時,需要提前獲取Condition對象關聯的鎖(在基于wait/notify方法實現的方案中需要獲取的是對象鎖)。

Condition對象是需要關聯Lock對象的,經調用Lock對象的newCondition()對象創建而來,也就是說Condition的使用是需要依賴Lock對象的。

下面是使用Condition的示范代碼:

private Lock lock = new ReentrantLock();
?? ?private Condition condition = lock.newCondition();
?
?? ?public void conditionAwait() throws InterruptedException {
?? ??? ?lock.lock();
?? ??? ?try {
?? ??? ??? ?condition.await();
?? ??? ?} finally {
?? ??? ??? ?lock.unlock();
?? ??? ?}
?? ?}
?
?? ?public void conditionSignal() {
?? ??? ?lock.lock();
?? ??? ?try {
?? ??? ??? ?condition.signal();//condition.signalAll();
?? ??? ?} finally {
?? ??? ??? ?lock.unlock();
?? ??? ?}
?? ?}


下面是關于Condition方法的一些簡單說明:

方法名稱
描述
await()

當前線程進入等待狀態直到被通知(signal)或者中斷;

當前線程進入運行狀態并從await()方法返回的場景包括:

(1)其他線程調用相同Condition對象的signal/signalAll方法,并且當前線程被喚醒;

(2)其他線程調用interrupt方法中斷當前線程;

awaitUninterruptibly()
當前線程進入等待狀態直到被通知,在此過程中對中斷信號不敏感,不支持中斷當前線程
awaitNanos(long)
當前線程進入等待狀態,直到被通知、中斷或者超時。如果返回值小于等于0,可以認定就是超時了
awaitUntil(Date)
當前線程進入等待狀態,直到被通知、中斷或者超時。如果沒到指定時間被通知,則返回true,否則返回false
signal()
喚醒一個等待在Condition上的線程,被喚醒的線程在方法返回前必須獲得與Condition對象關聯的鎖
signalAll()
喚醒所有等待在Condition上的線程,能夠從await()等方法返回的線程必須先獲得與Condition對象關聯的鎖

下面通過一個示例來簡單看看Condition是如何實現線程等待/通知機制的。

package?com.majing.java.concurrent;import?java.util.Arrays; import?java.util.concurrent.locks.Condition; import?java.util.concurrent.locks.Lock; import?java.util.concurrent.locks.ReentrantLock;public?class?BoundedQueue?{private?Integer[]?items;//定義為數組,在創建對象時就確定容量private?Lock?lock?=?new?ReentrantLock();private?Condition?notEmpty?=?lock.newCondition();private?Condition?notFull?=?lock.newCondition();private?int?count;private?int?addIndex,removeIndex;public?BoundedQueue(int?size){items?=?new?Integer[size];}public?void?add(Integer?object)?throws?InterruptedException{lock.lock();try{while(count==items.length){notFull.await();}items[addIndex]?=?object;if(++addIndex==items.length){addIndex?=?0;}count++;System.out.println(Thread.currentThread()+"?插入一個元素,數組為:"+Arrays.toString(items));notEmpty.signal();}finally{lock.unlock();}}@SuppressWarnings("unchecked")public?Integer?remove()?throws?InterruptedException{lock.lock();try{while(count==0){notEmpty.await();}Integer?temp?=?items[removeIndex];items[removeIndex]?=?null;System.out.println(Thread.currentThread()+"?移除一個元素,數組為:"+Arrays.toString(items));if(++removeIndex==items.length){removeIndex=0;}count--;notFull.signal();return?temp;}finally{lock.unlock();}} }

上面是有界隊列實現,下面寫個簡單的測試用例來測試這個有界隊列是否可靠。

package?com.majing.java.test;import?java.util.Random;import?com.majing.java.concurrent.BoundedQueue;public?class?Test?{private?static?final?Random?random?=?new?Random(System.currentTimeMillis());public?static?void?main(String[]?args)?throws?InterruptedException?{BoundedQueue?queue?=?new?BoundedQueue(5);for(int?i=1;i<=20;i++){Thread?thread?=?new?Thread(new?Producter(queue),String.valueOf(i));thread.start();}for(int?i=1;i<=20;i++){Thread?thread?=?new?Thread(new?Consumer(queue),String.valueOf(i));thread.start();}}static?class?Producter?implements?Runnable{private?BoundedQueue?queue;public?Producter(BoundedQueue?queue){this.queue?=?queue;}public?void?produce()?throws?InterruptedException{queue.add(new?Integer(random.nextInt(100)));}@Overridepublic?void?run()?{try?{produce();}?catch?(InterruptedException?e)?{e.printStackTrace();}}}static?class?Consumer?implements?Runnable{private?BoundedQueue?queue;public?Consumer(BoundedQueue?queue){this.queue?=?queue;}public?Integer?remove()?throws?InterruptedException{return?queue.remove();}@Overridepublic?void?run()?{try?{remove();}?catch?(InterruptedException?e)?{e.printStackTrace();}}} }

運行上面的代碼,結果如下:

Thread[1,5,main] 插入一個元素,數組為:[92, null, null, null, null]
Thread[2,5,main] 插入一個元素,數組為:[92, 87, null, null, null]
Thread[3,5,main] 插入一個元素,數組為:[92, 87, 19, null, null]
Thread[4,5,main] 插入一個元素,數組為:[92, 87, 19, 88, null]
Thread[5,5,main] 插入一個元素,數組為:[92, 87, 19, 88, 22]
Thread[1,5,main] 移除一個元素,數組為:[null, 87, 19, 88, 22]
Thread[2,5,main] 移除一個元素,數組為:[null, null, 19, 88, 22]
Thread[6,5,main] 插入一個元素,數組為:[23, null, 19, 88, 22]
Thread[7,5,main] 插入一個元素,數組為:[23, 26, 19, 88, 22]
Thread[3,5,main] 移除一個元素,數組為:[23, 26, null, 88, 22]
Thread[4,5,main] 移除一個元素,數組為:[23, 26, null, null, 22]
Thread[9,5,main] 插入一個元素,數組為:[23, 26, 30, null, 22]
Thread[8,5,main] 插入一個元素,數組為:[23, 26, 30, 83, 22]
Thread[5,5,main] 移除一個元素,數組為:[23, 26, 30, 83, null]
Thread[6,5,main] 移除一個元素,數組為:[null, 26, 30, 83, null]
Thread[7,5,main] 移除一個元素,數組為:[null, null, 30, 83, null]
Thread[10,5,main] 插入一個元素,數組為:[null, null, 30, 83, 25]
Thread[11,5,main] 插入一個元素,數組為:[13, null, 30, 83, 25]
Thread[12,5,main] 插入一個元素,數組為:[13, 30, 30, 83, 25]
Thread[9,5,main] 移除一個元素,數組為:[13, 30, null, 83, 25]
Thread[8,5,main] 移除一個元素,數組為:[13, 30, null, null, 25]
Thread[13,5,main] 插入一個元素,數組為:[13, 30, 9, null, 25]
Thread[14,5,main] 插入一個元素,數組為:[13, 30, 9, 4, 25]
Thread[10,5,main] 移除一個元素,數組為:[13, 30, 9, 4, null]
Thread[15,5,main] 插入一個元素,數組為:[13, 30, 9, 4, 85]
Thread[11,5,main] 移除一個元素,數組為:[null, 30, 9, 4, 85]
Thread[13,5,main] 移除一個元素,數組為:[null, null, 9, 4, 85]
Thread[16,5,main] 插入一個元素,數組為:[20, null, 9, 4, 85]
Thread[18,5,main] 插入一個元素,數組為:[20, 71, 9, 4, 85]
Thread[14,5,main] 移除一個元素,數組為:[20, 71, null, 4, 85]
Thread[17,5,main] 插入一個元素,數組為:[20, 71, 50, 4, 85]
Thread[16,5,main] 移除一個元素,數組為:[20, 71, 50, null, 85]
Thread[19,5,main] 插入一個元素,數組為:[20, 71, 50, 3, 85]
Thread[17,5,main] 移除一個元素,數組為:[20, 71, 50, 3, null]
Thread[18,5,main] 移除一個元素,數組為:[null, 71, 50, 3, null]
Thread[19,5,main] 移除一個元素,數組為:[null, null, 50, 3, null]
Thread[20,5,main] 插入一個元素,數組為:[null, null, 50, 3, 8]
Thread[20,5,main] 移除一個元素,數組為:[null, null, null, 3, 8]
Thread[12,5,main] 移除一個元素,數組為:[null, null, null, null, 8]
Thread[15,5,main] 移除一個元素,數組為:[null, null, null, null, null]

在這個例子中,實現了一個有界隊列,并且這個有界隊列的容量我控制在了5個元素,然后通過20個生產者和20個消費者并發去添加和取出元素,從運行結果來看,隊列并沒有出現異常,生產者和消費者能夠相互協調有序的進行。


轉載于:https://blog.51cto.com/12104971/2168932

總結

以上是生活随笔為你收集整理的Java并发与锁设计实现详述 - Java中的Condition的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: jizz免费观看 | 男人激情网 | 国产精品va| 久久久久久久偷拍 | 在线黄色免费网站 | 国产精品久久在线 | 欧美日韩一区二区三区在线观看 | 中文字幕无码精品亚洲35 | 欧美bbw视频 | 一区二区三区在线免费观看 | 天堂网中文在线观看 | 天天干夜操| 亚洲三级电影 | 高h教授1v1h喂奶| 国产欧美一区二区三区精品酒店 | 久久看片 | 欧美男女交配视频 | 大陆熟妇丰满多毛xxxⅹ | 色婷婷久久五月综合成人 | 69午夜 | 成人福利av | 国产日韩第一页 | www.日本在线视频 | 看看毛片 | 游戏涩涩免费网站 | 精品免费一区二区 | 国产精品欧美综合 | 四虎国产精品永久免费观看视频 | 波多野结衣中文字幕在线 | 69中国xxxxxxxxx69| 精品欧美乱码久久久久久1区2区 | 伊人98| 受虐m奴xxx在线观看 | 蜜桃在线一区二区三区 | 亚洲成人中文字幕 | 美日韩免费| 亚洲一区欧美激情 | 噜噜噜精品欧美成人 | 免费九九视频 | 国产精品国产三级国产传播 | 在线免费观看小视频 | 久久天天躁狠狠躁夜夜av | 日韩一级影片 | 欧美一区二区三区婷婷 | 国产成人精品一区二区在线小狼 | 黄色av免费播放 | 亚洲 精品 综合 精品 自拍 | 日韩精品h| 一级美女黄色片 | av鲁丝一区二区鲁丝 | 修仙淫交(高h)h文 | 日韩中文字幕在线 | 久久亚洲熟女cc98cm | 老牛影视少妇在线观看 | 亚洲视频一区在线 | 懂色av一区二区三区四区五区 | 国产午夜无码视频在线观看 | 少妇看片 | 永久久久久久久 | 成人性视频免费网站 | 国产破处视频 | 亚洲美女高潮久久久 | 在线电影一区二区三区 | 伊人春色在线视频 | 六月丁香激情综合 | 亚洲综合三区 | 青青草国产精品 | 国产一区二区三区高清 | 久久精品亚洲精品国产欧美 | 狠狠网站 | 国产精品成人久久久久久久 | 三级在线视频 | 综合激情久久 | 啪啪的网站 | 伊人久久精品 | 日本特级黄色录像 | 国产色综合视频 | 婷婷综合av | 日本免费三片在线播放 | 亚洲精品粉嫩小泬 | 亚洲成人av电影 | 无码人妻久久一区二区三区不卡 | 秋霞av鲁丝片一区二区 | av影视网| 免费在线不卡av | 欧美日韩理论 | 99久久精品国产成人一区二区 | 丁香六月激情 | 无码人妻一区二区三区线 | 经典毛片| 国产高清av在线 | 午夜一区在线观看 | 成年人在线观看视频网站 | 日韩视频中文字幕在线观看 | 北条麻妃av在线 | 91理论片午午伦夜理片久久 | 免费成人深夜夜 | 国产又粗又猛又爽又黄的视频小说 | 我要色综合天天 |