Class Semaphore
java.lang.Object
EDU.oswego.cs.dl.util.concurrent.Semaphore
- All Implemented Interfaces:
Sync
- Direct Known Subclasses:
QueuedSemaphore, WaiterPreferenceSemaphore
Base class for counting semaphores.
Conceptually, a semaphore maintains a set of permits.
Each acquire() blocks if necessary
until a permit is available, and then takes it.
Each release adds a permit. However, no actual permit objects
are used; the Semaphore just keeps a count of the number
available and acts accordingly.
A semaphore initialized to 1 can serve as a mutual exclusion lock.
Different implementation subclasses may provide different ordering guarantees (or lack thereof) surrounding which threads will be resumed upon a signal.
The default implementation makes NO guarantees about the order in which threads will acquire permits. It is often faster than other implementations.
Sample usage. Here is a class that uses a semaphore to help manage access to a pool of items.
class Pool {
static final MAX_AVAILABLE = 100;
private final Semaphore available = new Semaphore(MAX_AVAILABLE);
public Object getItem() throws InterruptedException { // no synch
available.acquire();
return getNextAvailableItem();
}
public void putItem(Object x) { // no synch
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 invalid input: '<' 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 invalid input: '<' MAX_AVAILABLE; ++i) {
if (item == items[i]) {
if (used[i]) {
used[i] = false;
return true;
}
else
return false;
}
}
return false;
}
}
-
Field Summary
FieldsFields inherited from interface Sync
ONE_CENTURY, ONE_DAY, ONE_HOUR, ONE_MINUTE, ONE_SECOND, ONE_WEEK, ONE_YEAR -
Constructor Summary
ConstructorsConstructorDescriptionSemaphore(long initialPermits) Create a Semaphore with the given initial number of permits. -
Method Summary
Modifier and TypeMethodDescriptionvoidacquire()Wait until a permit is available, and take onebooleanattempt(long msecs) Wait at most msecs millisconds for a permit.longpermits()Return the current number of available permits.voidrelease()Release a permitvoidrelease(long n) Release N permits.
-
Field Details
-
permits_
protected long permits_current number of available permits
-
-
Constructor Details
-
Semaphore
public Semaphore(long initialPermits) Create a Semaphore with the given initial number of permits. Using a seed of one makes the semaphore act as a mutual exclusion lock. Negative seeds are also allowed, in which case no acquires will proceed until the number of releases has pushed the number of permits past 0.
-
-
Method Details
-
acquire
Wait until a permit is available, and take one- Specified by:
acquirein interfaceSync- Throws:
InterruptedException
-
attempt
Wait at most msecs millisconds for a permit.- Specified by:
attemptin interfaceSync- Parameters:
msecs- the number of milleseconds to wait. An argument less than or equal to zero means not to wait at all. However, this may still require access to a synchronization lock, which can impose unbounded delay if there is a lot of contention among threads.- Returns:
- true if acquired
- Throws:
InterruptedException
-
release
-
release
public void release(long n) Release N permits.release(n)is equivalent in effect to:for (int i = 0; i invalid input: '<' n; ++i) release();But may be more efficient in some semaphore implementations.
- Throws:
IllegalArgumentException- if n is negative.
-
permits
public long permits()Return the current number of available permits. Returns an accurate, but possibly unstable value, that may change immediately after returning.
-