Java多執行緒併發工具類-訊號量Semaphore物件講解

dapan發表於2021-09-09

Java多執行緒併發工具類-Semaphore物件講解

透過前面的學習,我們已經知道了Java多執行緒併發場景中使用比較多的兩個工具類:做加法的CycliBarrier物件以及做減法的CountDownLatch物件並對這兩個物件進行了比較。我們發現這兩個物件要麼是做加法,要麼是做減法的。那麼有沒有既做加法也做減法的呢?當然有了。Semaphore這個工具類就可以實現One out one in的。

本文主要內容:Semaphore是什麼?從生活中例子中來理解Semaphore;程式碼演示;總結。透過總結-理解-程式碼演示-再總結這四個步驟讓大家來深刻的理解。

本篇是《凱哥(凱哥Java:kagejava)併發程式設計學習》系列之《併發工具類》教程的第三篇:《Java多執行緒下訊號量》。

一:Semaphore是什麼?

Semaphore中文意思:訊號量。

來看看JavaAPI中對semaphore物件的解釋:

圖片描述

什麼意思呢?

簡單理解來說,Semaphore:訊號量主要用於兩個目的:一個是用於多個共享資源的互斥使用;另一個用於併發執行緒數量的控制。什麼意思呢?我們來從生活中的例子來理解。

二:從生活中例子中來理解Semaphore

案例一:搶車位

自駕遊的朋友一般都會遇到這樣的煩惱:去景區遊玩,停車比較麻煩。因為停車場中的車位數量是一定的。當車位滿了以後,其他想要進入停車場停車的車輛只能等待。等到其他車輛出來之後,才可以進入。站在併發角度來分析的話:停車場有多個停車位(多個共享資源),每個車輛只能停在其中一個位置上(互斥使用的),停車場的停車位是固定的(併發執行緒數量的控制)。這樣是不是就好理解了?如果還是不好理解,接著看下面這個案例

案例二:海底撈吃火鍋

去海底撈吃火鍋的時候,海底撈場地就餐桌數量是固定的,假設有5桌。現在來了8個人,那麼其他3個就需要在門口候餐區等待加號。當有其他桌吃完離開之後,進去一個。簡圖如下:

三:程式碼演示

我們就來模擬海底撈吃火鍋的場景。

圖片描述

3.1:為什麼要使用Semaphore?

為什麼不能使用其他兩個同步工具類呢?

根據CountDownLatch的特性,只能使用一次的特徵來說,海底撈這種場景當然不能夠使用了。因為開個店不可能只使用一次。

CyclicBarrier,雖然可以使用多次,但是需要reset之後才可以多次使用。意思就是,只有等餐廳裡面5個桌的客人都吃完之後,才可以讓其他人進來就餐的。這種情況也是不符合業務邏輯的。

而Semaphore可以做到One out One in 很適合海底撈的場景。所以,經過分析,我們可以得到如下程式碼。

程式碼演示:

餐桌物件:

圖片描述

執行方法:

圖片描述

執行結果:

圖片描述

從執行結果中,我們可以看到一個進入一個就離開,一個離開餐桌下一位就進入餐廳就餐。達到我們預期結果了。

四:總結

4.1:使用語法

在宣告smaphore的時候需要設定執行緒數量。然後使用acquire獲取資源。在finally方法裡面呼叫release方法進行釋放資源。如下圖:

圖片描述

4.2:內部主要組成

4.2.1:三個內部類:

看到這三個類是不是很熟悉?對就是我們前面介紹的ReentrantLock和ReentrantReadWriteLock這兩個物件裡面都存在的。繼承AQS的Sync類以及公平鎖的FairSync類和非公平鎖的NonfairSync類。同樣,semaphore也支援在構造器中指定是公平還是非公平的:

4.2.2:主要方法

重要的方法獲取和釋放方法:

獲取資源的:

acquire/acquire(int permits):獲取資源(許可證)/獲取指定個數的資源

釋放資源:

release/release(int permits):釋放資源/釋放指定個數的資源

其他方法:

阻止獲取資源:

acquireUninterruptibly/acquireUninterruptibly(int permits):從這個訊號燈獲取許可證,阻止一個可用的/阻止指定數量的

獲取當前可以用的資源數量: int availablePermits

還有其他很多方法。凱哥這裡就不一一介紹了。大家可以自行檢視API

4.3:實現原理

看到Sync這個內部類之後,大家就應該想到了凱哥(kaigejava)在之前介紹過的AQS物件了。沒錯,Semaphore就是使用AQS和CAS來實現資源的獲取和釋放的。在這裡凱哥就不贅述了。大家可以看看前面凱哥介紹併發容器的同步器相關文章,裡面凱哥做了詳細的介紹。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/758/viewspace-2825221/,如需轉載,請註明出處,否則將追究法律責任。

相關文章