什麼是 Java Semaphore 和 Mutex – Java Concurrency MultiThread 舉例說明

已發表: 2015-03-12

Crunchify 的 Java Mutex 和信號量教程

Java並發是一個非常廣泛的話題。 有數百個教程和示例可供使用。 前段時間我寫過一些關於在 Java 中並發運行多個線程和不同類型的同步塊的教程。

在本教程中,我們將介紹:

  1. 互斥量的解釋
  2. 信號量的解釋
  3. 兩個有細節的例子

讓我們開始吧

在閱讀以下說明時Let's keep this in mind

  • 以 Shopper 和 Customer 為例
  • 購物者正在藉筆記本電腦
  • 客戶可以來使用筆記本電腦——客戶需要鑰匙才能使用筆記本電腦
  • 使用後 – 客戶可以將筆記本電腦退還給購物者

什麼是互斥鎖(只有 1 個線程):

購物者有筆記本電腦的鑰匙。 一位客戶當時可以擁有鑰匙——借用一台筆記本電腦。 當任務完成時,Shopper 將鑰匙交給(釋放)隊列中的下一位顧客。

Official Definition

“互斥鎖通常用於序列化對cannot be executed concurrently的可re-entrant code部分的訪問。 互斥對像只允許一個線程進入受控部分,迫使試圖訪問該部分的其他線程等待,直到第一個線程退出該部分。”

換句話說: Mutex = Mutually Exclusive Semaphore

什麼是信號量(N個指定線程):

假設現在 Shopper 有 3 台相同的筆記本電腦和 3 個相同的鑰匙。 信號量是free identical Laptop keys的數量。 信號量計數——鍵的數量——在開始時設置為 3(所有三台筆記本電腦都是空閒的),然後隨著客戶進來,計數值遞減。如果所有筆記本電腦都在使用,即沒有空閒鍵可供使用筆記本電腦,信號量計數為 0。現在,當任何客戶返回筆記本電腦時,信號量增加到 1(一個空閒密鑰),並提供給隊列中的下一個客戶。

Official Definition :“信號量將共享資源的同時用戶數限制為最大數量。 線程可以請求對資源的訪問(減少信號量),並且可以發出信號表明它們已經完成了對資源的使用(增加信號量)。”

另一個必須閱讀:單例線程安全實例的延遲創建

示例 1:(解釋如下)

在上面的教程CrunchifySemaphoreMutexTutorial.java ,當CrunchifyProducerthreadName添加到crunchifyList linkedList 對象時,它可以發出信號量信號。

然後, CrunchifyConsumer可以嘗試獲取信號量,因此它們將一直等待,直到 CrunchifyProducer 發出已添加線程 ID 的信號。 在發出添加數據的信號後,其中一個消費者將被喚醒,它會知道它可以讀取一個 crunchifyList 對象。 它可以讀取一個列表,然後返回嘗試獲取信號量。

如果在那個時候生產者已經寫入了另一個數據包,它會再次發出信號,然後任何一個消費者將繼續讀取另一個數據包,依此類推……

換一種說法:

結果:

如何防止競態條件:

What if you have multiple Consumers? 在上面的 Java 教程中,消費者(不是生產者)在讀取數據包時(而不是在獲取信號量時)應該鎖定緩衝區,以防止出現競爭條件。 在下面的示例中,生產者還鎖定了列表,因為所有內容都在同一個 JVM 上。

示例 2:

結果: