计数信号量用来控制同时访问某个特定资源的操作数量或者同时执行某个指定操作的数量。可以用来实现某种资源池(数据库连接池)或对容器施加边界。
例如:使用Semaphore来为容器设置边界
思路:将Semaphore的计数值为池的大小,并从池中获取一个资源之前先调用acquire方法获取一个许可,在将资源返回给池之后调用release释放许可,那么
acquire将一直阻塞直到资源池不为空。
public class BoundedHashSet<T> {
private final Set<T> set;
private final Semaphore sem;
public BoundedHashSet(int bound) {
this.set = Collections.synchronizedSet(new HashSet<>());
sem = new Semaphore(bound);
}
public boolean add(T o) throws InterruptedException {
sem.acquire();
boolean wasAdded = false;
try {
wasAdded = set.add(o);
return wasAdded;
}finally {
//如果add没有添加任何元素会立即释放
if (!wasAdded) {
sem.release();
}
}
}
public boolean remove(Object o) {
boolean wasRemoved = set.remove(o);
if (wasRemoved) {
sem.release();
}
return wasRemoved;
}
}