Semaphore是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理使用公共资源。
可以用于流量控制,特别是公用资源有限的应用场景,比如数据库连接。
Semaphore的用法很简单,首先线程使用acquire()方法获取一个许可证,使用完之后调用release()方法归还许可证。还可以用tryAcquire()方法尝试获取许可证。
acquire()方法最后的实现逻辑分公平锁和非公平锁
//公平锁的获取方式protected int tryAcquireShared(int acquires) {//自旋尝试获取共享锁for (;;) {//是否有线程在等待,有就返回失败if (hasQueuedPredecessors())return -1;int available = getState();int remaining = available - acquires;//还有许可证,并且同步状态修改成功,返回剩余许可数if (remaining < 0 ||compareAndSetState(available, remaining))return remaining;}}//不公平锁的获取方式,区别就在于不再判断是否有线程在等待,而是直接尝试获取许可final int nonfairTryAcquireShared(int acquires) {for (;;) {int available = getState();int remaining = available - acquires;if (remaining < 0 ||compareAndSetState(available, remaining))return remaining;}}
//释放锁protected final boolean tryReleaseShared(int releases) {for (;;) {int current = getState();int next = current + releases;if (next < current) // overflowthrow new Error("Maximum permit count exceeded");if (compareAndSetState(current, next))return true;}}
其他一些方法:
int availablePermits();返回此信号量中当前可用的许可证数
int getQueueLength();返回正在等待获取许可证的线程数
Boolean hasQueuedThreads();是否有线程正在等待获取许可证
void reducePermits();减少reduction个许可证,是protected方法
collection getQueuedThreads();返回所有等待获取许可证的线程集合,是个protected方法
