Semaphore 是一个计数信号量。从概念上讲,信号量管理着一组虚拟的许可,许可的初始数量可通过构造函数来指定。在执行操作前要首先获得许可,并在使用之后释放许可。如果获取不到许可,那么 acquire()将阻塞直到有许可获得为止。每个 release() 将返回一个许可给信号量。。说白了,Semaphore是一个计数器,在计数器不为0的时候对线程就放行,一旦达到0,那么所有请求资源的新线程都会被阻塞。每一次请求一个许可都会导致计数器减少1,同样每次释放一个许可都会导致计数器增加1,一旦达到了0,新的许可请求线程将被挂起。缓存池也是使用此思想来实现的,比如链接池、对象池等。
下面是一个例子:
package net.jcip.examples;
import java.util.*;
import java.util.concurrent.*;
public 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;
}
}
使用信号量将任何一种容器变为有界阻塞容器,在调用add方法向底层容器添加一个元素前,要先获得一个许可,如果获取不到,则阻塞,删除掉一个元素时,则释放一个许可返回给信号量。