一,計數(shù)信號量(Counting Semaphore)概述
- 計數(shù)信號量(Counting Semaphore)用來控制同時訪問某個特定資源的操作數(shù)量,或者同時執(zhí)行某個指定操作的數(shù)量.計數(shù)信號量還可以用來實現(xiàn)某種資源池,或者對容器施加邊界
- Semaphore中管理著一組虛擬的許可(Permit),許可的初始數(shù)量可通過構(gòu)造函數(shù)來指定.在執(zhí)行操作時可以首先獲得許可(只要還有剩余的許可),并在使用以后釋放許可.如果沒有許可,那么acquire將阻塞直到有許可(或者直到被中斷或者操作超時).release方法將返回一個許可信號量.
- 計數(shù)信號量的一種簡化形式是二值信號量,即初始值為1的Semaphore,二值信號量可以用做互斥體(mutex),并具備不可重入的加鎖語義:誰擁有這個唯一許可,誰就擁有了互斥鎖
- 可以使用Semaphore將任何一種容器編程有界阻塞容器
二,利用Semaphore實現(xiàn)一個有界阻塞容器示例
信號量的計數(shù)值會初始化為容器容量的最大值.add操作在向底層容器中添加一個元素之前,首先要獲取一個許可.如果add操作沒有添加任何元素,那么會立刻釋放許可.同樣,remove操作釋放一個許可,使更多的元素能夠添加到容器中.
class BoundedHashSet<T> {
private final Set<T> set;
private final 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(Object o) {
boolean wasRemoved = set.remove(o);
if (wasRemoved) {
sem.release();
}
return wasRemoved;
}
}
參考:
<<java編發(fā)編程實戰(zhàn)>>