簡體   English   中英

可重入鎖條件公平

[英]Reentrant lock condition fairness

我對ReentrantLockCondition感到困惑。 這是文檔:

  • 等待線程以 FIFO 順序發出信號。

  • 從等待方法返回的線程重新獲取鎖的順序與最初獲取鎖的線程相同,在默認情況下未指定,但對於公平鎖,優先考慮那些等待時間最長的線程。

根據最新的子彈,公平性帶來了一個明確的信號鎖定重新獲取順序。

但是第一個子彈的含義是什么等待線程以 FIFO 順序發出信號 我認為在這種情況下,信號僅意味着“信號”,這意味着它以 FIFO 順序“解除”線程,但喚醒時的實際重新獲取順序由公平性決定。

有相當多的員工與 cxq 相關聯,HotSpot 內部的等待隊列我不太了解(不幸的是)。


問題

等待線程以 FIFO 順序發出信號是否意味着等待線程以它們被停放的相同順序解除停放(即使鎖本身是不公平的)?

由於在一般情況下存在 unpark-require 競賽,公平性是否提供了必要的重新獲取排序保證?

正如“fair”和“unfair”鎖的內部存儲差異中所解釋的,“fair”和“unfair”之間的實際區別不是隊列的組織,而是在不公平模式下,嘗試獲取鎖的線程可能即使隊列中已經有等待線程,也會成功。 這樣的超車線程根本不會與隊列交互。

Condition上調用其中一個await方法的線程必須已經擁有關聯的鎖並將釋放它,以便另一個線程可以獲取它,滿足條件並調用signalsignalAll 所以線程必須自己入隊,以便其他線程知道要向哪個線程發出信號。 調用signal時,從 FIFO 中取出等待條件最長時間的線程。

發出信號的線程可能未停放,但也有可能尚未停放。 在任何一種情況下,它都必須重新獲取鎖,並且這種重新獲取受到鎖的公平保證。 到線程調用signal時,它必須擁有鎖。 因此,發出信號的線程不能立即成功。 當鎖被釋放時,多個線程之間可能會發生競爭。

但是一個條件的 FIFO 順序的信號意味着當兩個或多個線程在相同的條件上等待並且一個得到信號時,它將是等待時間最長的線程,並且其他線程都不能超過,即使對於不公平的鎖也是如此。 只有當多個線程發出信號或其他線程,不等待條件時,才嘗試獲取鎖,不公平鎖的獲取順序是任意的。 此外,正如鏈接的答案所提到的, tryLock()即使在公平鎖上也可能會超過。

閱讀 ReentrantLock (Java 12) 的源碼我們可以看到,與公平和不公平 ReentrantLock 的區別很小。 區別在於擴展 java.util.concurrent.locks.AbstractQueuedSynchronizer 的 class。 在一種情況下是 FairSync,在另一種情況下是 NonfairSync。 兩者都在 ReentrantLock 中定義,唯一的區別是 FairSync 在方法 tryAcquire 中實現了另一項檢查。 閱讀代碼似乎在非公平 ReentrantLock FIFO 的最佳條件下也受到尊重,但由於取消、超時或類似情況,這不能保證。 在公平的 ReentrantLock 中,獲取鎖之前的任何線程(如果從隊列中取消駐留)重新檢查是否有較舊的線程。 我不確定是否理解第二個問題,但請注意釋放鎖的線程已從隊列中取消駐留線程。 此外,如果釋放鎖的線程將隊列中的舊線程解鎖,這不足以避免飢餓,因為第三個線程可能需要在退出線程解鎖等待的線程之前同時獲得鎖。 在公平模式下,每次有新線程嘗試獲得鎖時,都會檢查所有等待的線程,並且此被授予者 FIFO 並避免飢餓。

等待線程的外部中斷不會改變隊列順序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM