本文介紹了Java公平信號量的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我正在嘗試理解這個舊考試任務的答案,在這個考試任務中,學生應該使用Java重入鎖來實現公平的二進制信號量。我不明白這些計數器的意義:
int next = 0;
int nextToGo = 0;
int myNumber;
它在對任務的描述中說:”您可以假設程序中最多有20個線程使用信號量。此外,在程序的一次運行中最多執行1000萬個信號量操作。”
在任務的解決方案中,它說:”每個試圖獲取信號量的線程都必須在隊列中注冊自己,并且只有在之前的線程離開它之后才能離開隊列。每個線程使用32位計數器來記住它在隊列中的位置。計數器不會回繞,因為最多會對信號量執行1000萬次操作,但即使計數器可能回繞,代碼也可以運行。”
在我看來,老師似乎在解決方案中忽略了1000萬個線程的限制,但我的主要問題是,當線程被放入lock()和aWait()語句中的隊列中,并且有一個正在檢查的自由變量時,為什么需要計數器。而ReentrantLock(True)難道不考慮公平性嗎?
解決方案:
public class FairSemaphore {
ReentrantLock l = new ReentrantLock(true);
Condition c = l.newCondition();
int next = 0;
int nextToGo = 0;
boolean free = true;
public void aqcuire() throws InterruptedException {
l.lock();
int myNumber = next++;
while(!(free && myNumber == nextToGo)) {
c.await();
}
free = false;
nextToGo++;
l.unlock();
}
public void release() {
l.lock();
free = true;
c.signalAll();
l.unlock();
}
}
推薦答案
雖然您可能會認為在可重入鎖上阻塞的線程
排隊,不能保證隊列的行為像FIFO一樣公平
排隊。文檔明確告訴您:
…此鎖不保證任何特定的訪問權限
秩序。
..。但是請注意,鎖的公平性并不能保證線程調度的公平性。…
閱讀全文docs,即使您創建了公平的ReentrantLock,也不能保證它是公平的。
但是,顯示的代碼確實運行正常,因為計數器使線程以FIFO順序獲取鎖。
代碼是票證鎖,因此也請簽出https://en.wikipedia.org/wiki/Ticket_lock
這篇關于Java公平信號量的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,