日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

java condition_(原创)Java的ReentrantLock(可重入锁)下的Condition

發布時間:2025/3/20 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java condition_(原创)Java的ReentrantLock(可重入锁)下的Condition 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

先來看一下這個Condition的使用場景,在LinkedBlockingQueue(鏈表的阻塞隊列)類中包含如下的定義,通過使用lock.newCondition()方法,可以獲得一個Condition對象,說明Condition與ReentrantLock有著重要的關聯關系。

Condition對象創建

通常它們的使用方式是如下這樣,注意線程1的condition.await()和線程2的condition.signal()方法,后面重點講解這兩個方法。

例子

Condition類是AQS(AbstractQueuedSynchronizer,抽象的隊列同步器)的內部類,我們重點來看下這個線程1的condition.await()方法,對里面的幾個重要方法進行重點的說明。

await()方法

Node node = addConditionWaiter();//將當前線程包裝成Node,然后放入條件等待隊列中,注意這個隊列和//外面的ReentrantLock的同步等待隊列是兩個不同的隊列,在喚醒時(也就是調用condition.signal()),會把//這個線程先從條件等待隊列中移除,然后轉移到ReentrantLock的同步等待隊列里面去,然后在同步等待隊列//中獲取鎖以后,才能真正的被執行int savedState = fullyRelease(node);//在將當前線程放入到條件等待隊列中以后,這個方法會把當前線程//所持有的鎖釋放掉,這個時候ReentrantLock同步等待隊列中的某一個線程會獲得鎖,然后被激活int interruptMode = 0;while (!isOnSyncQueue(node)) {//判斷當前線程如果不存在于ReentrantLock同步隊列中,則將當前線程//中斷掛起,如果這個線程存在于ReentrantLock同步隊列中,那么它已經被中斷掛起,則不需要再次中斷掛起 LockSupport.park(this);

總結來說就是,將當前線程封裝成Node,然后加入到條件等待隊列中,釋放線程持有的鎖,然后將此線程中斷掛起。

接下來我們重點來看下線程2的condition.signal()方法,對里面的幾個重要方法進行重點的說明。

signal()方法

if (!isHeldExclusively())//判斷此線程是不是ReentrantLock鎖的獨占線程,如果不是則拋出異常,換言之//只有是ReentrantLock鎖的獨占線程,才能進行喚醒操作,也就是說在執行condition.await()//和condition.signal()方法時,線程必須拿到ReentrantLock鎖才可以進行,這也就是Condition //與ReentrantLock有著必要的關聯關系 throw new IllegalMonitorStateException(); Node first = firstWaiter;//拿到條件等待線程的第一個Node if (first != null) doSignal(first);//第一個Node不為null時,進行喚醒操作

下面來看下doSignal(first)方法的執行邏輯,重點看下其中的transferForSignal(first)方法。

doSignal()方法

transferForSignal()方法

if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))//將Node的節點更新為0,如果更新失敗, //則代表此節點已經被取消了,直接返回失敗,遍歷下一個條件等待隊列的節點。 return false;Node p = enq(node);//重點方法,將當前節點由條件等待隊列轉移到ReentrantLock的同步等待隊列的隊尾中去 int ws = p.waitStatus;//此時被轉移到同步等待隊列的Node的waitStatus應該是0, if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))//將此Node節點的waitStatus更新為-1 LockSupport.unpark(node.thread);//此邏輯不會執行,因為線程從條件等待隊列只是被轉移到了同步 //等待隊列,而且是隊尾的位置,如果同步等待隊列前面有有其他線程,則會優先于它被喚醒。 return true;

在執行了condition.signal()方法后,會將條件等待隊列中的線程移除,然后轉移到ReentrantLock的同步等待隊列中,后面的邏輯就和ReentrantLock(可重入鎖)執行同步等待隊列中的線程一樣了(這個邏輯不清楚可以查看我的此篇文章(原創)Java的ReentrantLock(可重入鎖)詳解上篇)。

簡單總結下,Condition依賴于ReentrantLock,必須拿到ReentrantLock鎖以后,才可以進行await()和single()方法,在執行了await()時,會釋放持有的ReentrantLock鎖,并把自己加入到條件等待隊列中去,在執行了single()時,會把線程從條件等待隊列轉移到ReentrantLock的同步等待隊列中去,然后等待被真正的執行。

總結

以上是生活随笔為你收集整理的java condition_(原创)Java的ReentrantLock(可重入锁)下的Condition的全部內容,希望文章能夠幫你解決所遇到的問題。

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