簡體   English   中英

Java 解鎖后線程執行順序

[英]Java thread execution order after unlock

假設我有 2 個線程, t1t2 ,以及一個鎖 object, m 線程t1處於無限循環中,在每次迭代中,它都會在m上獲取一個鎖,做一些工作,解鎖m並立即重新開始。 在一次迭代中, t2請求鎖定m ,但被t1阻塞並必須等待。 現在,當t1解鎖m時,是否保證t2將獲得m的下一個鎖? 還是t1可以在下一次迭代中搶先一步?

一般來說,是否為等待線程設置了隊列? 如果t1有鎖,並且所有剩余線程也希望該鎖按以下順序被阻塞: t2t3 ,...,剩余線程是否會按照它們被阻塞的順序繼續執行(例如t2運行,然后t3 , ETC。)?

(我簡要閱讀了 java 規范,但找不到答案。如果它在那里,請告訴我,我將 go 回來仔細閱讀。)

謝謝,(第一個 SO 帖子,哇哦!)

是的,有一個隊列,它可以公平或不公平。 公平隊列更昂貴,非公平隊列更快(誰贏得了 CAS 就贏得了鎖)。 檢查java.util.concurrent.locks.AbstractQueuedSynchronizer了解更多信息。

剩余的線程是否會按照它們被阻塞的順序繼續執行(例如 t2 運行,然后 t3 等)?

主要問題是它們同時/同時執行,您無法真正定義同時執行的 2 個事件的順序。 但是 w/ fair(由於額外成本不推薦)鎖定任何設法為自己爭取鎖的線程最終將擁有它。

不,沒有這樣的保證。 您可以建議 Java 是ReentrantLock 對象是公平的,但這是建議性的,不保證任何順序。

通常,您不能(沒有顯式同步來實現它)保證這樣的順序,因為t2可能在它甚至獲取線程之前就已被中斷,並且完全由操作系統決定何時恢復哪個線程。

不,不能保證大多數用途。 你會注意到一些 java.util.concurrent 抽象提供了“公平鎖”的選項——它或多或少地保證了每個等待鎖的線程最終都會被調用(不是特定的順序)。 沒有公平,就沒有保障。 OTOH,公平是非常昂貴的。 (有關某些基准,請參閱 Java 實踐中的並發性),通常,概率可能性就足夠了。

您可以使用 fair Semaphore來保證訂單。 標准內置 Java 鎖/監視器不公平,不以公平的方式排隊訂單。

Semaphore sem = new Semaphore(1, true);

//usage:
sem.acquire();
try {
  //holding a lock
  //of course both threads share the same semaphore
} finally {
  sem.release();
}

理論上,有了鎖,T1 可以在釋放它后在下一次迭代中再次獲取鎖,盡管事實上 T2 已經在等待它。 不太可能,但可能。

暫無
暫無

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

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