Semaphore 美[ˈseməfɔːr]
信号量Semaphore 可以用于做流量控制,特别是公用资源有限的应用场景,比如数据库连接。Semaphore的构造方法
Semaphore(int permits)接受一个整型的数字,表示可用的许可证数量。Semaphore(10)表示允许10个线程获取许可证,也就是最大并发数是10。
Semaphore的用法也很简单,首先使用Semaphore的acquire()方法获取一个许可证,使用完之后调用release()方法归还许可证。调用acquire()如果没有获取到许可证会持续等待直到获取到许可证。
还可以用tryAcquire()方法尝试获取许可证,返回的是一个boolean,可以根据boolean来执行获取许可证失败后的处理逻辑。
Semaphore的其他方法:
int availablePermits():返回此信号量中当前可用的许可证数。
int getQueueLength():返回正在等待获取许可证的线程数。
boolean hasQueuedThreads():是否有线程正在等待获取许可证。
void reducePermits(int reduction):减少reduction个许可证,是个protected方法。
Collection getQueuedThreads():返回所有等待获取许可证的线程集合,是个protected方法。
使用Semaphore控制容器边界样例
import java.util.*; import java.util.concurrent.*; /** * BoundedHashSet * <p/> * Using Semaphore to bound a collection * * @author Brian Goetz and Tim Peierls */ 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; } }