public class Semaphore extends Object implements Serializable
acquire()
块如果必要的许可证前,是可用的,然后把它。每个
release()
添加许可,潜在收购方释放阻塞。然而,不使用实际允许的对象;
Semaphore
只是计数的数量和相应的行为。
信号量通常是用来限制线程的数量比可以访问一些(物理或逻辑)资源。例如,这里是一个类使用一个信号量来控制访问的项目池:
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;
}
}
获得一项前,每个线程必须从信号量获取许可证,保证可以使用该项。当线程已完成的项目是返回到池中并允许返回信号,允许另一个线程获得该项目。注意,没有同步锁时举行acquire()
称为阻止一项被返回到池。信号量的封装需要限制访问的库同步,分别从任何同步需要保持一致性本身的游泳池。
一个信号量初始化为一个,使得它在使用时最多只有一个可用的许可,可以作为一个互斥锁。这是通常被称为一个二进制信号量,因为它只有两种状态:一个可用的许可,或零的许可证。采用这种方式时,二进制信号的性质(不像许多Lock
实现),即“锁”可以比其他业主线程释放(如信号量没有概念的所有权)。这可能是有用的,在一些专门的情况下,如死锁恢复。
此类的构造函数可以选择接受一个公平参数。当设置错误时,这个类没有保证线程获取许可证的顺序。特别是,闯入是允许的,即一个线程调用acquire()
可以分配一个许可证在一个线程一直等待在新线程将自己在等待线程队列的头部。当公平设置为真,信号量保证线程调用任何的acquire
方法选择的顺序在它们调用这些方法处理获得的许可(先出;第一FIFO)。值得注意的是,FIFO顺序不一定适用于执行特定的内部点在这些方法。因此,一个线程调用另一个acquire
之前,它是可能的,但在其他到达订货点,同样从方法返回时。还要注意,不定时的tryAcquire
方法不尊重公平设置,但会采取任何许可证,可。
一般来说,信号量用于控制资源的访问应初始化为公平,确保任何线程饥饿访问。当使用其他种类的同步控制信号,非公平排序的吞吐量优势往往大于公平的考虑。
该类还提供了方便的方法来acquire
和release
多证一次。当使用这些方法时,不考虑公平性集的时候,要提防无限期延迟的风险增加。
内存一致性效果:行动中的线程之前调用一个“释放”的方法,如release()
happen-before行动成功后“获得”的方法,如在另一个线程acquire()
。
Constructor and Description |
---|
Semaphore(int permits)
创建一个
Semaphore 与给定数量的许可证和nonfair公平设置。
|
Semaphore(int permits, boolean fair)
创建一个允许给定数量
Semaphore 和给定的公平环境。
|
Modifier and Type | Method and Description |
---|---|
void |
acquire()
从这个信号获取许可证,阻塞直到有一个可用的线程,或是
interrupted。
|
void |
acquire(int permits)
获得了从这个信号量许可证号码,阻塞直到所有的线程可用,或是
interrupted。
|
void |
acquireUninterruptibly()
从这个信号获取许可证,阻塞直到有可用的。
|
void |
acquireUninterruptibly(int permits)
获得了从这个信号量许可证号码,阻塞直到所有可用。
|
int |
availablePermits()
返回当前在该信号量可用许可证号码。
|
int |
drainPermits()
获取并返回立即可用的所有许可证。
|
protected Collection<Thread> |
getQueuedThreads()
返回一个包含可能等待获取的线程的集合。
|
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)
获得了从这个信号量许可证号码,如果所有可用在给定的等待时间和当前线程没有被
interrupted。
|
boolean |
tryAcquire(long timeout, TimeUnit unit)
从这个信号获取许可证,如果有一个可用在给定的等待时间和当前线程没有被
interrupted。
|
public Semaphore(int permits)
Semaphore
与给定数量的许可证和nonfair公平设置。
permits
-初始数量的许可证。此值可能是负的,在这种情况下,必须发生的情况下,任何收购将被授予。
public Semaphore(int permits, boolean fair)
Semaphore
和给定的公平环境。
permits
-初始数量的许可证。此值可能是负的,在这种情况下,必须发生的情况下,任何收购将被授予。
fair
-
true
如果这个信号将保证先进先出的发放许可证的争夺下,其他
false
public void acquire() throws InterruptedException
获得一个许可证,如果一个是可用的,并立即返回,减少了可用的许可证的数量。
如果没有可用的许可证,那么目前的线程成为禁用线程调度的目的,并处于休眠状态,直到两个事情发生:
release()
方法和当前线程下被分配一个许可证;或如果当前线程:
InterruptedException
投入和当前线程的中断状态被清除。
InterruptedException
-如果当前线程被中断
public void acquireUninterruptibly()
获得一个许可证,如果一个是可用的,并立即返回,减少了可用的许可证的数量。
如果没有许可证是获得当前线程的线程调度的目的成为残疾人和处于休眠状态,直到其他线程调用此信号量的release()
方法和当前线程被分配一个许可证下。
如果当前线程interrupted在等待许可证就会继续等待,但时间的线程分配一个许可证可能会改变相比,它可能会收到许可证没有中断发生的时间。当线程确实从这个方法返回时,它的中断状态将被设置。
public boolean tryAcquire()
获得许可证,如果有,立即返回,与价值true
,由一个减少可用的许可数。
如果没有许可证可用此方法将立即返回的值false
。
甚至当这个信号被设置为使用公平有序的政策,呼吁tryAcquire()
将立即如果有获得许可证,是否有其他线程正在等待。这种“闯”的行为在某些情况下可能是有用的,即使它打破了公平。如果你想尊重公平设置,然后使用tryAcquire(0, TimeUnit.SECONDS)
几乎是等价的(它也检测到中断)。
true
如果许可证的获得和
false
否则
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException
获得许可证,如果有,立即返回,与价值true
,由一个减少可用的许可数。
如果没有可用的许可证,那么目前的线程成为禁用线程调度的目的,并处于休眠状态,直到三个事情发生:
release()
方法和当前线程下被分配一个许可证;或如果许可证获得的价值true
然后返回。
如果当前线程:
InterruptedException
投入和当前线程的中断状态被清除。
如果指定的等待时间的流逝,然后false
返回值。如果时间小于或等于零,该方法将不会等待在所有。
timeout
-最大时间等待许可证
unit
的
timeout
争论的时间单位
true
如果许可证的获得和
false
如果等待的时间才获得许可证
InterruptedException
-如果当前线程被中断
public void release()
发布一个许可证,增加一个可用的许可证的数量。如果任何线程试图获得一个许可证,那么一个选择和给定的许可证,刚刚发布。该线程是(重新)启用线程调度的目的。
不要求一个线程释放许可证必须取得许可证,通过调用acquire()
。一个信号量的正确使用是由应用程序中的确立。
public void acquire(int permits) throws InterruptedException
获得给定数量的许可证,如果他们是可用的,并立即返回,减少可用的许可证的数量由给定的金额。
如果没有足够的许可证,那么目前的线程成为禁用线程调度的目的,并处于休眠状态,直到两个事情发生:
release
方法,当前线程被分配许可证和下一个可用的许可数满足这一要求;或如果当前线程:
InterruptedException
投入和当前线程的中断状态被清除。这是分配给该线程的任何许可证而不是分配给其他线程试图获取许可证,如果允许被调用提供了
release()
。
permits
-许可数量的获得
InterruptedException
-如果当前线程被中断
IllegalArgumentException
-如果
permits
是负的
public void acquireUninterruptibly(int permits)
获得给定数量的许可证,如果他们是可用的,并立即返回,减少可用的许可证的数量由给定的金额。
如果没有足够的许可证可以再当前线程的线程调度的目的成为残疾人和处于休眠状态,直到其他线程调用这一信号的release
方法,当前线程被分配许可证和下一个可用的许可数满足这个要求。
如果当前线程在等待许可证interrupted则继续等待在队列中的位置不受影响。当线程确实从这个方法返回时,它的中断状态将被设置。
permits
-许可数量的获得
IllegalArgumentException
-如果
permits
是负的
public boolean tryAcquire(int permits)
获取给定数量的许可证,如果他们是可用的,并立即返回,与价值true
,由一定数量的减少可使用的许可证的数量。
如果没有足够的许可证可用此方法将立即返回的值false
和可用的许可证的数量是不变的。
甚至当这个信号被设置为使用公平有序的政策,呼吁tryAcquire
将立即如果有获得许可证,是否有其他线程正在等待。这种“闯”的行为在某些情况下可能是有用的,即使它打破了公平。如果你想尊重公平设置,然后使用tryAcquire(permits, 0, TimeUnit.SECONDS)
几乎是等价的(它也检测到中断)。
permits
-许可数量的获得
true
如果许可证的获得和
false
否则
IllegalArgumentException
-如果
permits
是负的
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException
获取给定数量的许可证,如果他们可以立即返回,与价值true
,由一定数量的减少可使用的许可证的数量。
如果没有足够的许可证是可用的,那么目前的线程成为禁用线程调度的目的,并处于休眠状态,直到三个事情发生:
release
方法,当前线程被分配许可证和下一个可用的许可数满足这一要求;或如果许可证获得的价值true
然后返回。
如果当前线程:
InterruptedException
投入和当前线程的中断状态被清除。这是分配给该线程的任何许可证,而不是分配给其他线程试图获取许可证,如果允许被调用提供了
release()
。
如果指定的等待时间的流逝,然后false
返回值。如果时间小于或等于零,该方法将不会等待在所有。这是分配给该线程的任何许可证,而不是分配给其他线程试图获取许可证,如果允许被调用提供了release()
。
permits
-许可数量的获得
timeout
-最大时间等待许可证
unit
的
timeout
争论的时间单位
true
如果允许被收购,
false
如果等待的时间才获得了所有许可证
InterruptedException
-如果当前线程被中断
IllegalArgumentException
-如果
permits
是负的
public void release(int permits)
释放给定数量的许可证,增加可用的许可证数量由该金额。如果任何线程试图获得许可证,那么一个选择和给定的许可证,刚刚发布。如果可用的许可数满足该线程的请求,那么该线程是(重新)启用线程调度的目的;否则线程将等待,直到有足够的许可证是可用的。如果该线程的请求得到满足后,仍然可以使用许可证,那么这些许可证将被分配给试图获得许可证的其他线程。
不要求一个线程释放许可证必须取得许可证,通过调用acquire
。一个信号量的正确使用是由应用程序中的确立。
permits
-许可数量的释放
IllegalArgumentException
-如果
permits
是负的
public int availablePermits()
此方法通常用于调试和测试目的。
public int drainPermits()
protected void reducePermits(int reduction)
acquire
:不阻塞等待许可证可用。
reduction
-许可数量的去除
IllegalArgumentException
-如果
reduction
是负的
public boolean isFair()
true
公平设置为true。
true
公平设置为true
public final boolean hasQueuedThreads()
true
返回不保证其他线程会获得。这种方法的设计主要是用于监测系统状态。
true
如果可能有其他线程等待获取锁
public final int getQueueLength()
protected Collection<Thread> getQueuedThreads()
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.