1. 程式人生 > >Java執行緒之訊號量

Java執行緒之訊號量

 計數訊號量用來控制同時訪問某個特定資源的運算元量,或者同時執行某個指定操作的數量。計數訊號量還可以用來實現某種資源池,或者對容器施加邊界。
Semaphore中管理者一組虛擬的許可,許可的數量可通過建構函式來指定。在互相操作時可以首先獲得許可(只要還有剩餘的許可),並在使用以後釋放許可。如果沒有許可,那麼acquire將阻塞直到有許可(或者直到被中斷或者操作超時)。release方法將返回一個許可給訊號量。計算訊號量的一種簡化形式是二值訊號量,即初始值為1的Semaphore,二值訊號量可以用做互斥體,並不具備可重入的加鎖語義:誰擁有這個唯一的許可,誰就擁有了互斥鎖。
Semaphore

可以用來實現資源池,例如資料庫連線池。我們可以構造一個固定長度的資源池,當池為空時,請求資源將會失敗,但你真正希望看到的行為是阻塞而不是失敗,並且當池非空時解除阻塞。如果將Semaphore的計數值初始化為池的大小,並在從池中獲取一個資源之前先首先呼叫acquire方法獲取一個許可,在將資源返回給池之後呼叫release釋放許可,那麼acquire將一直阻塞直到資源池不為空。

public class BoundedHashSet<T> {
    private Set<T> set;
    private Semaphore sem;

    public BoundedHashSet
(int bound) { this.set = Collections.synchronizedSet(new HashSet<T>()); sem = new Semaphore(bound);//傳入的許可數量,可以控制每次訪問的執行緒的數量 } public boolean add(T o) throws InterruptedException { sem.acquire(); boolean wasAdded = false; try { wasAdded =
set.add(o); return wasAdded; } finally { if (!wasAdded) { sem.release(); } } } public boolean remove(Objects o) { boolean wasRemove = set.remove(o); if (wasRemove) { sem.release(); } return wasRemove; } }

 根據Semaphore特性,我們可以來控制每次訪問資源的執行緒數量。