Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。例如,下面的类使用信号量控制对内容池的访问:
方法详解:
构造方法摘要 | |
---|---|
Semaphore(int permits) 创建具有给定的许可数和非公平的公平设置的 Semaphore 。 |
|
Semaphore(int permits, boolean fair) 创建具有给定的许可数和给定的公平设置的 Semaphore 。 |
方法摘要 | |
---|---|
void |
acquire() 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。 |
void |
acquire(int permits) 从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。 |
void |
acquireUninterruptibly() 从此信号量中获取许可,在有可用的许可前将其阻塞。 |
void |
acquireUninterruptibly(int permits) 从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞。 |
int |
availablePermits() 返回此信号量中当前可用的许可数。 |
int |
drainPermits() 获取并返回立即可用的所有许可。 |
protected Collection<Thread> |
getQueuedThreads() 返回一个 collection,包含可能等待获取的线程。 |
int |
getQueueLength() 返回正在等待获取的线程的估计数目。 |
boolean |
hasQueuedThreads() 查询是否有线程正在等待获取。 |
boolean |
isFair() 如果此信号量的公平设置为 true,则返回 true 。 |
protected void |
reducePermits(int reduction) 根据指定的缩减量减小可用许可的数目。 |
void |
release() 释放一个许可,将其返回给信号量。 |
void |
release(int permits) 释放给定数目的许可,将其返回到信号量。 |
String |
toString() 返回标识此信号量的字符串,以及信号量的状态。 |
boolean |
tryAcquire() 仅在调用时此信号量存在一个可用许可,才从信号量获取许可。 |
boolean |
tryAcquire(int permits) 仅在调用时此信号量中有给定数目的许可时,才从此信号量中获取这些许可。 |
boolean |
tryAcquire(int permits, long timeout, TimeUnit unit) 如果在给定的等待时间内此信号量有可用的所有许可,并且当前线程未被中断,则从此信号量获取给定数目的许可。 |
boolean |
tryAcquire(long timeout, TimeUnit unit) 如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。 |
//API中示例代码
class Pool { private static final int MAX_AVAILABLE = 100; private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); public Object getItem() throws InterruptedException { available.acquire(); return getNextAvailableItem(); } public void putItem(Object x) { if (markAsUnused(x)) available.release(); } // Not a particularly efficient data structure; just for demo protected Object[] items = ... whatever kinds of items being managed protected boolean[] used = new boolean[MAX_AVAILABLE]; protected synchronized Object getNextAvailableItem() { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (!used[i]) { used[i] = true; return items[i]; } } return null; // not reached } protected synchronized boolean markAsUnused(Object item) { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (item == items[i]) { if (used[i]) { used[i] = false; return true; } else return false; } } return false; } }