簡體   English   中英

二進制信號量 vs 可重入鎖

[英]Binary Semaphore vs a ReentrantLock

我一直在嘗試了解可重入鎖和信號量(可重入鎖與釋放/解鎖機制的嵌套)。

似乎擁有 Semaphore 需要您編寫經過更徹底測試的應用程序,因為 release() 方法不會檢查釋放許可的線程是否實際持有它。 當我測試我的測試代碼時,我發現這可能會導致許可證數量增加超出初始限制。 另一方面,如果一個線程在調用 unlock 方法時沒有持有可重入鎖,我們會得到一個 IllegalMonitorException。

所以說沒有真正的理由擁有二進制信號量是對的,因為二進制信號量可以做的一切也可以通過 ReentrantLock 來完成。 如果我們使用二進制信號量,我們將不得不檢查整個方法調用堆棧以查看之前是否獲得了許可(如果有后續獲得的可能性,它是否也被釋放 - 如果釋放不繼續,這可能會阻塞它和等等)。 此外,由於可重入鎖還為每個對象提供一個鎖,與二進制信號量相比,更喜歡重入鎖是否總是更好的主意?

我在這里查看了一篇文章,其中討論了二進制信號量和互斥鎖之間的區別,但是在 Java 中有沒有像互斥鎖這樣的東西?

謝謝,陳。

PS - 我在另一個論壇( http://www.coderanch.com/t/615796/threads/java/reason-prefer-binary-Semaphore-Reentrant )發布了這個問題,但我還沒有收到回復。 我想我也會把它貼在這里,看看我能得到什么。

沒有真正的理由擁有二進制信號量,因為二進制信號量可以做的一切也可以通過 ReentrantLock 來完成

如果您只需要可重入互斥,那么是的,沒有理由在 ReentrantLock 上使用二進制信號量。 如果出於任何原因您需要非所有權釋放語義,那么顯然信號量是您唯一的選擇。

此外,由於可重入鎖還為每個對象提供一個鎖,與二進制信號量相比,更喜歡重入鎖是否總是更好的主意?

這取決於需要。 如前所述,如果您需要一個簡單的互斥鎖,則不要選擇信號量。 如果多個線程(但數量有限)可以進入臨界區,您可以通過線程限制或信號量來實現。

我在這里查看了一篇文章,其中討論了二進制信號量和互斥鎖之間的區別,但是在 Java 中有沒有像互斥鎖這樣的東西?

ReentrantLocksynchronized是 Java 中互斥鎖的例子。

我不會解釋可重入鎖,因為 John 已經在上面給出了很好的解釋,它是 Java 中互斥鎖和 Synchronized 關鍵字的示例。

但是,如果出於任何原因,您想更好地控制鎖定機制,信號量可以變得很方便。 這意味着,您的代碼必須繼續負責誰調用了acquire() 和誰調用了release(),因為信號量本質上對它視而不見,它所關心的只是允許可用。

使用 java 實現自己的互斥鎖的另一種方法是 LockSupport。 它的工作方式有點像信號量,但在許可上有一個超時,使用 park() 函數,並且一次只支持一個許可,而信號量則支持多個許可。

信號量和重入鎖之間有一些小的區別。

  • 信號量可能被另一個線程釋放。 Semaphore 的 javadoc 聲明這種行為可能在一些特殊的上下文中很有用,比如死鎖恢復。 所以它應該是一個真正專門的上下文。
  • 二進制信號量也不是可重入的。 您不能在同一線程中第二次獲取二進制信號量。 它會導致死鎖(使線程與自身發生死鎖!)並且您可能需要一些已經提到的死鎖恢復方法

暫無
暫無

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

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