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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

并发编程实践三:Condition

發布時間:2023/12/18 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 并发编程实践三:Condition 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Condition實例始終被綁定到一個鎖(Lock)上。Lock替代了Java的synchronized方法,而Condition則替代了Object的監視器方法,包含wait、notify和notifyAll(想很多其它的了解能夠看我的博客:Java并發編程3-等待、通知和中斷)。而在Condition中相應為await、signal和signalAll。這篇文章主要講述Condition的用法。以及它的實現機制。

Condition的使用

與Object的監視器方法不同。每一個Lock能夠相應多個Condition對象,這樣等待的線程就能夠分散到多個等待集合中。就能夠針對不同的等待集合來依次喚醒線程。實現喚醒效率的提高(不再須要喚醒全部線程)。看以下的樣例:

public class BoundedBuffer {final Lock lock = new ReentrantLock();final Condition notFull = lock.newCondition();final Condition notEmpty = lock.newCondition();final Object[] items = new Object[100];int putptr, takeptr, count;public void put(Object x) throws InterruptedException {lock.lock();try {while (count == items.length)notFull.await();items[putptr] = x;if (++putptr == items.length)putptr = 0;++count;notEmpty.signal(); //喚醒一個take線程} finally {lock.unlock();}}public Object take() throws InterruptedException {lock.lock();try {while (count == 0)notEmpty.await();Object x = items[takeptr];if (++takeptr == items.length)takeptr = 0;--count;notFull.signal(); //喚醒一個put線程return x;} finally {lock.unlock();}} }


以下我們來看看Condition的主要方法:

await

造成當前線程在接到信號或被中斷之前一直處于等待狀態。
與此Condition相關的鎖以原子方式釋放,而且出于線程調度的目的,將禁用當前線程,且在發生下面四種情況之中的一個曾經,當前線程將一直處于休眠狀態:
?1)其它某個線程調用此Condition的signal()方法,而且碰巧將當前線程選為被喚醒的線程。或者
?2)其它某個線程調用此Condition的signalAll()方法。或者
?3)其它某個線程中斷當前線程,且支持中斷線程的掛起;或者
?4)已超過指定的等待時間。或者
?5)發生“虛假喚醒”。


在全部情況下。在此方法返回到當前線程前。都必須又一次獲取與此條件有關的鎖。
await支持無參數版本號(一直等待)、帶時間參數的版本號(僅僅等待指定時間或等待至某個時間)和支持不可中斷的等待。

signal

喚醒一個等待線程。


假設全部的線程都在等待此條件。則選擇當中的一個喚醒。在從 await 返回之前,該線程必須又一次獲取鎖。

signalAll

喚醒全部等待線程。
假設全部的線程都在等待此條件,則喚醒全部線程。在從 await 返回之前,每一個線程都必須又一次獲取鎖。

在使用Condition時,須要注意的是Condition的實例本身也是一個Object,也帶有wait、notify和notifyAll方法,注意不要搞混。

Condition的實現

AbstractQueuedLongSynchronizer.ConditionObject是Condition的詳細實現類,使用了一個FIFO隊列來保存等待的線程,await將一個線程放入等待隊列中,signal每次喚醒等待時間最長的線程(而notify則是隨意喚醒一個線程)。signalAll則喚醒全部等待線程。等待隊列的節點使用和AQS的隊列同樣的節點(見上一篇:“并發編程實踐二:AbstractQueuedSynchronizer”),隊列的head和tail的定義例如以下:

public class ConditionObject implements Condition, java.io.Serializable {private transient Node firstWaiter;private transient Node lastWaiter;。。。

。。。 }


?

和AQS不同的是,ConditionObject使用nextWaiter指向下一個節點(AQS中使用prev和next),而且waitStatus屬性值為Node.CONDITION。

當一個線程獲取了鎖后,它能夠調用該鎖相應的Condition的await方法將自己堵塞:
?1)假設當前線程被中斷,則拋出中斷異常;
?2)將當前線程放置到Condition的等待隊列中;
?3)釋放當前線程的鎖,而且保存鎖定狀態;
?4)在收到信號、中斷或超時前,一直堵塞;
?5)使用保存的鎖定狀態又一次獲取鎖;
?6)假設步驟4的堵塞過程中發生中斷,則拋出中斷異常。

public final void await() throws InterruptedException {if (Thread.interrupted()) //1throw new InterruptedException();Node node = addConditionWaiter(); //2int savedState = fullyRelease(node); //3int interruptMode = 0;while (!isOnSyncQueue(node)) { //4LockSupport.park(this);if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)break;}if (acquireQueued(node, savedState) && interruptMode != THROW_IE) //5interruptMode = REINTERRUPT;if (node.nextWaiter != null) // clean up if cancelledunlinkCancelledWaiters();if (interruptMode != 0) //6reportInterruptAfterWait(interruptMode); }


?

整個過程并不復雜,須要注意的是堵塞須要放在一個循環中。防止“虛假喚醒”,之所以要保存鎖定狀態,是為了使用排它模式來獲取鎖。

線程能夠調用signal來將當前Condition的等待隊列中的第一個節點移動到擁有鎖的等待隊列:
?1)假設不是排它模式。則拋出IllegalMonitorStateException異常。
?2)將等待隊列的第一個節點出隊列,并將其增加AQS的鎖隊列。

public final void signal() {if (!isHeldExclusively()) //1throw new IllegalMonitorStateException();Node first = firstWaiter;if (first != null)doSignal(first); //2 } private void doSignal(Node first) {do {if ( (firstWaiter = first.nextWaiter) == null)lastWaiter = null;first.nextWaiter = null;} while (!transferForSignal(first) &&(first = firstWaiter) != null); } final boolean transferForSignal(Node node) {if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))return false;Node p = enq(node);int ws = p.waitStatus;if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))LockSupport.unpark(node.thread);return true; }


將因為signal總是從隊列的第一個節點開始處理。因此總是能夠保持喚醒的次序。
signal一開始就運行isHeldExclusively推斷是否為排它模式,在ReentrantLock中的實現例如以下:

protected final boolean isHeldExclusively() {return getExclusiveOwnerThread() == Thread.currentThread(); }


也就是當當前線程為鎖的擁有者時。才繼續運行。而在transferForSignal中,假設節點的waitStatus不是CONDITION,那么就僅僅會是CANCELLED(在await操作中運行fullyRelease時。假設失敗會將節點的waitStatus設置到CANCELLED);enq將節點增加AQS的堵塞隊列,返回節點的前續節點,當前續節點被取消(ws > 0),或者更改狀態失敗(這里同意失敗,失敗后被喚醒的線程在acquireQueued中會再次設置前續節點的狀態,直到成功)后,將運行喚醒線程的操作。

線程也能夠調用signalAll將全部線程從此Condition的等待隊列移動到擁有鎖的等待隊列。

public final void signalAll() {if (!isHeldExclusively())throw new IllegalMonitorStateException();Node first = firstWaiter;if (first != null)doSignalAll(first); } private void doSignalAll(Node first) {lastWaiter = firstWaiter = null;do {Node next = first.nextWaiter;first.nextWaiter = null;transferForSignal(first);first = next;} while (first != null); }


signalAll在doSignalAll中依次調用transferForSignal將Condition的等待隊列中的全部節點移動到鎖的等待隊列中。

結束語

Condition在設計時就充分考慮了Object的監視器方法的缺陷。一個lock能夠相應多個Condition,從而能夠使線程分散到多個等待隊列中,使應用更為靈活,而且在實現上使用了FIFO隊列來保存等待線程,確保了能夠做到使用signal按FIFO方式喚醒等待線程。避免每次喚醒全部線程導致數據競爭。
Condition這種設計相同也導致使用上要比Object的監視器方法更為復雜,你須要考慮使用多少個Condition。在什么地方使用哪個condition等等?因為Condition是和Lock配合使用的。所以是否使用Condition須要和Lock一起綜合考慮。

轉載于:https://www.cnblogs.com/mengfanrong/p/5109351.html

總結

以上是生活随笔為你收集整理的并发编程实践三:Condition的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 五月婷婷丁香 | 国产精品乱码久久久久久久久 | 日本毛片网站 | 香蕉影院在线观看 | caoprom在线 | a级黄视频 | 国产无码精品一区二区 | 精品一性一色一乱农村 | 亚洲欧洲自拍偷拍 | 欧美影视一区二区三区 | 自拍偷拍 国产 | 日韩三级一区二区三区 | 蜜乳av一区| 欧美一区二区三区激情视频 | 亚洲最大毛片 | 亚洲专区在线视频 | 少妇人妻偷人精品一区二区 | www国产视频 | 韩国美女毛片 | 男人插入女人下面视频 | 天天干网 | 国产一级免费在线观看 | 好色av | 阿v视频在线免费观看 | 日韩成人在线观看视频 | 麻豆视屏| 91蝌蚪91九色| √天堂资源在线 | 一个人看的www片免费高清中文 | 精品丝袜一区 | 国产香蕉视频 | 女人叫床很黄很污句子 | 一个色综合网站 | 亚洲区自拍偷拍 | 高潮毛片无遮挡 | 国产v亚洲v天堂无码久久久 | 日本一区二区在线播放 | 欧美超碰在线 | 成人深夜网站 | 直接看的毛片 | 成人午夜视频在线播放 | 久久精品欧美日韩精品 | 中文字幕不卡在线观看 | 成人在线国产精品 | 亚洲欧美日本另类 | 九九热九九爱 | 人妻精品久久久久中文字幕69 | 久草免费福利视频 | 深爱激情丁香 | 黄色网在线播放 | 亚洲美女操 | 一级生活毛片 | 国产在线成人 | 波多野结衣片子 | 中文字幕在线网 | 黄色无毒网站 | 小蝌蚪av | 日韩图片一区 | 日韩视频免费观看高清完整版在线观看 | aaaaa级少妇高潮大片免费看 | 99色亚洲| 亚洲大片免费观看 | 成人毛片在线视频 | 亚洲女人被黑人巨大进入 | 日韩不卡一区二区三区 | 色欧美88888久久久久久影院 | 无码人妻一区二区三区av | 曰本无码人妻丰满熟妇啪啪 | 久久久国产精品久久久 | 极品白嫩丰满少妇无套 | 国产毛片自拍 | 青青草这里只有精品 | 一区二区三区四区中文字幕 | 亚洲自拍在线观看 | 国产综合精品视频 | 人妻少妇精品一区二区 | 成人精品三级av在线看 | 亚洲一二三四在线 | 久久久88| 中国a级黄色片 | 国产成人午夜精品无码区久久 | 日本变态折磨凌虐bdsm在线 | 国产精品一卡二卡 | 天堂视频在线免费观看 | 污污网站免费在线观看 | 毛片网站有哪些 | 色婷婷在线观看视频 | 狠狠操在线视频 | 久草久热 | 波多野结衣视频网站 | 国产精品一级片在线观看 | 国产草逼视频 | 成人国产一区二区三区 | 中文字幕第66页 | 韩国三级视频在线观看 | 不卡中文字幕在线观看 | 中国av毛片 | 性色av一区| 精品久久蜜桃 |