1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Semaphore.java Sat Mar 19 10:46:31 2016 +0100
1.3 @@ -0,0 +1,713 @@
1.4 +/*
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.6 + *
1.7 + * This code is free software; you can redistribute it and/or modify it
1.8 + * under the terms of the GNU General Public License version 2 only, as
1.9 + * published by the Free Software Foundation. Oracle designates this
1.10 + * particular file as subject to the "Classpath" exception as provided
1.11 + * by Oracle in the LICENSE file that accompanied this code.
1.12 + *
1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.16 + * version 2 for more details (a copy is included in the LICENSE file that
1.17 + * accompanied this code).
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License version
1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.22 + *
1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.24 + * or visit www.oracle.com if you need additional information or have any
1.25 + * questions.
1.26 + */
1.27 +
1.28 +/*
1.29 + * This file is available under and governed by the GNU General Public
1.30 + * License version 2 only, as published by the Free Software Foundation.
1.31 + * However, the following notice accompanied the original version of this
1.32 + * file:
1.33 + *
1.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
1.35 + * Expert Group and released to the public domain, as explained at
1.36 + * http://creativecommons.org/publicdomain/zero/1.0/
1.37 + */
1.38 +
1.39 +package java.util.concurrent;
1.40 +import java.util.*;
1.41 +import java.util.concurrent.locks.*;
1.42 +import java.util.concurrent.atomic.*;
1.43 +
1.44 +/**
1.45 + * A counting semaphore. Conceptually, a semaphore maintains a set of
1.46 + * permits. Each {@link #acquire} blocks if necessary until a permit is
1.47 + * available, and then takes it. Each {@link #release} adds a permit,
1.48 + * potentially releasing a blocking acquirer.
1.49 + * However, no actual permit objects are used; the {@code Semaphore} just
1.50 + * keeps a count of the number available and acts accordingly.
1.51 + *
1.52 + * <p>Semaphores are often used to restrict the number of threads than can
1.53 + * access some (physical or logical) resource. For example, here is
1.54 + * a class that uses a semaphore to control access to a pool of items:
1.55 + * <pre>
1.56 + * class Pool {
1.57 + * private static final int MAX_AVAILABLE = 100;
1.58 + * private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
1.59 + *
1.60 + * public Object getItem() throws InterruptedException {
1.61 + * available.acquire();
1.62 + * return getNextAvailableItem();
1.63 + * }
1.64 + *
1.65 + * public void putItem(Object x) {
1.66 + * if (markAsUnused(x))
1.67 + * available.release();
1.68 + * }
1.69 + *
1.70 + * // Not a particularly efficient data structure; just for demo
1.71 + *
1.72 + * protected Object[] items = ... whatever kinds of items being managed
1.73 + * protected boolean[] used = new boolean[MAX_AVAILABLE];
1.74 + *
1.75 + * protected synchronized Object getNextAvailableItem() {
1.76 + * for (int i = 0; i < MAX_AVAILABLE; ++i) {
1.77 + * if (!used[i]) {
1.78 + * used[i] = true;
1.79 + * return items[i];
1.80 + * }
1.81 + * }
1.82 + * return null; // not reached
1.83 + * }
1.84 + *
1.85 + * protected synchronized boolean markAsUnused(Object item) {
1.86 + * for (int i = 0; i < MAX_AVAILABLE; ++i) {
1.87 + * if (item == items[i]) {
1.88 + * if (used[i]) {
1.89 + * used[i] = false;
1.90 + * return true;
1.91 + * } else
1.92 + * return false;
1.93 + * }
1.94 + * }
1.95 + * return false;
1.96 + * }
1.97 + *
1.98 + * }
1.99 + * </pre>
1.100 + *
1.101 + * <p>Before obtaining an item each thread must acquire a permit from
1.102 + * the semaphore, guaranteeing that an item is available for use. When
1.103 + * the thread has finished with the item it is returned back to the
1.104 + * pool and a permit is returned to the semaphore, allowing another
1.105 + * thread to acquire that item. Note that no synchronization lock is
1.106 + * held when {@link #acquire} is called as that would prevent an item
1.107 + * from being returned to the pool. The semaphore encapsulates the
1.108 + * synchronization needed to restrict access to the pool, separately
1.109 + * from any synchronization needed to maintain the consistency of the
1.110 + * pool itself.
1.111 + *
1.112 + * <p>A semaphore initialized to one, and which is used such that it
1.113 + * only has at most one permit available, can serve as a mutual
1.114 + * exclusion lock. This is more commonly known as a <em>binary
1.115 + * semaphore</em>, because it only has two states: one permit
1.116 + * available, or zero permits available. When used in this way, the
1.117 + * binary semaphore has the property (unlike many {@link Lock}
1.118 + * implementations), that the "lock" can be released by a
1.119 + * thread other than the owner (as semaphores have no notion of
1.120 + * ownership). This can be useful in some specialized contexts, such
1.121 + * as deadlock recovery.
1.122 + *
1.123 + * <p> The constructor for this class optionally accepts a
1.124 + * <em>fairness</em> parameter. When set false, this class makes no
1.125 + * guarantees about the order in which threads acquire permits. In
1.126 + * particular, <em>barging</em> is permitted, that is, a thread
1.127 + * invoking {@link #acquire} can be allocated a permit ahead of a
1.128 + * thread that has been waiting - logically the new thread places itself at
1.129 + * the head of the queue of waiting threads. When fairness is set true, the
1.130 + * semaphore guarantees that threads invoking any of the {@link
1.131 + * #acquire() acquire} methods are selected to obtain permits in the order in
1.132 + * which their invocation of those methods was processed
1.133 + * (first-in-first-out; FIFO). Note that FIFO ordering necessarily
1.134 + * applies to specific internal points of execution within these
1.135 + * methods. So, it is possible for one thread to invoke
1.136 + * {@code acquire} before another, but reach the ordering point after
1.137 + * the other, and similarly upon return from the method.
1.138 + * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
1.139 + * honor the fairness setting, but will take any permits that are
1.140 + * available.
1.141 + *
1.142 + * <p>Generally, semaphores used to control resource access should be
1.143 + * initialized as fair, to ensure that no thread is starved out from
1.144 + * accessing a resource. When using semaphores for other kinds of
1.145 + * synchronization control, the throughput advantages of non-fair
1.146 + * ordering often outweigh fairness considerations.
1.147 + *
1.148 + * <p>This class also provides convenience methods to {@link
1.149 + * #acquire(int) acquire} and {@link #release(int) release} multiple
1.150 + * permits at a time. Beware of the increased risk of indefinite
1.151 + * postponement when these methods are used without fairness set true.
1.152 + *
1.153 + * <p>Memory consistency effects: Actions in a thread prior to calling
1.154 + * a "release" method such as {@code release()}
1.155 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
1.156 + * actions following a successful "acquire" method such as {@code acquire()}
1.157 + * in another thread.
1.158 + *
1.159 + * @since 1.5
1.160 + * @author Doug Lea
1.161 + *
1.162 + */
1.163 +
1.164 +public class Semaphore implements java.io.Serializable {
1.165 + private static final long serialVersionUID = -3222578661600680210L;
1.166 + /** All mechanics via AbstractQueuedSynchronizer subclass */
1.167 + private final Sync sync;
1.168 +
1.169 + /**
1.170 + * Synchronization implementation for semaphore. Uses AQS state
1.171 + * to represent permits. Subclassed into fair and nonfair
1.172 + * versions.
1.173 + */
1.174 + abstract static class Sync extends AbstractQueuedSynchronizer {
1.175 + private static final long serialVersionUID = 1192457210091910933L;
1.176 +
1.177 + Sync(int permits) {
1.178 + setState(permits);
1.179 + }
1.180 +
1.181 + final int getPermits() {
1.182 + return getState();
1.183 + }
1.184 +
1.185 + final int nonfairTryAcquireShared(int acquires) {
1.186 + for (;;) {
1.187 + int available = getState();
1.188 + int remaining = available - acquires;
1.189 + if (remaining < 0 ||
1.190 + compareAndSetState(available, remaining))
1.191 + return remaining;
1.192 + }
1.193 + }
1.194 +
1.195 + protected final boolean tryReleaseShared(int releases) {
1.196 + for (;;) {
1.197 + int current = getState();
1.198 + int next = current + releases;
1.199 + if (next < current) // overflow
1.200 + throw new Error("Maximum permit count exceeded");
1.201 + if (compareAndSetState(current, next))
1.202 + return true;
1.203 + }
1.204 + }
1.205 +
1.206 + final void reducePermits(int reductions) {
1.207 + for (;;) {
1.208 + int current = getState();
1.209 + int next = current - reductions;
1.210 + if (next > current) // underflow
1.211 + throw new Error("Permit count underflow");
1.212 + if (compareAndSetState(current, next))
1.213 + return;
1.214 + }
1.215 + }
1.216 +
1.217 + final int drainPermits() {
1.218 + for (;;) {
1.219 + int current = getState();
1.220 + if (current == 0 || compareAndSetState(current, 0))
1.221 + return current;
1.222 + }
1.223 + }
1.224 + }
1.225 +
1.226 + /**
1.227 + * NonFair version
1.228 + */
1.229 + static final class NonfairSync extends Sync {
1.230 + private static final long serialVersionUID = -2694183684443567898L;
1.231 +
1.232 + NonfairSync(int permits) {
1.233 + super(permits);
1.234 + }
1.235 +
1.236 + protected int tryAcquireShared(int acquires) {
1.237 + return nonfairTryAcquireShared(acquires);
1.238 + }
1.239 + }
1.240 +
1.241 + /**
1.242 + * Fair version
1.243 + */
1.244 + static final class FairSync extends Sync {
1.245 + private static final long serialVersionUID = 2014338818796000944L;
1.246 +
1.247 + FairSync(int permits) {
1.248 + super(permits);
1.249 + }
1.250 +
1.251 + protected int tryAcquireShared(int acquires) {
1.252 + for (;;) {
1.253 + if (hasQueuedPredecessors())
1.254 + return -1;
1.255 + int available = getState();
1.256 + int remaining = available - acquires;
1.257 + if (remaining < 0 ||
1.258 + compareAndSetState(available, remaining))
1.259 + return remaining;
1.260 + }
1.261 + }
1.262 + }
1.263 +
1.264 + /**
1.265 + * Creates a {@code Semaphore} with the given number of
1.266 + * permits and nonfair fairness setting.
1.267 + *
1.268 + * @param permits the initial number of permits available.
1.269 + * This value may be negative, in which case releases
1.270 + * must occur before any acquires will be granted.
1.271 + */
1.272 + public Semaphore(int permits) {
1.273 + sync = new NonfairSync(permits);
1.274 + }
1.275 +
1.276 + /**
1.277 + * Creates a {@code Semaphore} with the given number of
1.278 + * permits and the given fairness setting.
1.279 + *
1.280 + * @param permits the initial number of permits available.
1.281 + * This value may be negative, in which case releases
1.282 + * must occur before any acquires will be granted.
1.283 + * @param fair {@code true} if this semaphore will guarantee
1.284 + * first-in first-out granting of permits under contention,
1.285 + * else {@code false}
1.286 + */
1.287 + public Semaphore(int permits, boolean fair) {
1.288 + sync = fair ? new FairSync(permits) : new NonfairSync(permits);
1.289 + }
1.290 +
1.291 + /**
1.292 + * Acquires a permit from this semaphore, blocking until one is
1.293 + * available, or the thread is {@linkplain Thread#interrupt interrupted}.
1.294 + *
1.295 + * <p>Acquires a permit, if one is available and returns immediately,
1.296 + * reducing the number of available permits by one.
1.297 + *
1.298 + * <p>If no permit is available then the current thread becomes
1.299 + * disabled for thread scheduling purposes and lies dormant until
1.300 + * one of two things happens:
1.301 + * <ul>
1.302 + * <li>Some other thread invokes the {@link #release} method for this
1.303 + * semaphore and the current thread is next to be assigned a permit; or
1.304 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
1.305 + * the current thread.
1.306 + * </ul>
1.307 + *
1.308 + * <p>If the current thread:
1.309 + * <ul>
1.310 + * <li>has its interrupted status set on entry to this method; or
1.311 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
1.312 + * for a permit,
1.313 + * </ul>
1.314 + * then {@link InterruptedException} is thrown and the current thread's
1.315 + * interrupted status is cleared.
1.316 + *
1.317 + * @throws InterruptedException if the current thread is interrupted
1.318 + */
1.319 + public void acquire() throws InterruptedException {
1.320 + sync.acquireSharedInterruptibly(1);
1.321 + }
1.322 +
1.323 + /**
1.324 + * Acquires a permit from this semaphore, blocking until one is
1.325 + * available.
1.326 + *
1.327 + * <p>Acquires a permit, if one is available and returns immediately,
1.328 + * reducing the number of available permits by one.
1.329 + *
1.330 + * <p>If no permit is available then the current thread becomes
1.331 + * disabled for thread scheduling purposes and lies dormant until
1.332 + * some other thread invokes the {@link #release} method for this
1.333 + * semaphore and the current thread is next to be assigned a permit.
1.334 + *
1.335 + * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
1.336 + * while waiting for a permit then it will continue to wait, but the
1.337 + * time at which the thread is assigned a permit may change compared to
1.338 + * the time it would have received the permit had no interruption
1.339 + * occurred. When the thread does return from this method its interrupt
1.340 + * status will be set.
1.341 + */
1.342 + public void acquireUninterruptibly() {
1.343 + sync.acquireShared(1);
1.344 + }
1.345 +
1.346 + /**
1.347 + * Acquires a permit from this semaphore, only if one is available at the
1.348 + * time of invocation.
1.349 + *
1.350 + * <p>Acquires a permit, if one is available and returns immediately,
1.351 + * with the value {@code true},
1.352 + * reducing the number of available permits by one.
1.353 + *
1.354 + * <p>If no permit is available then this method will return
1.355 + * immediately with the value {@code false}.
1.356 + *
1.357 + * <p>Even when this semaphore has been set to use a
1.358 + * fair ordering policy, a call to {@code tryAcquire()} <em>will</em>
1.359 + * immediately acquire a permit if one is available, whether or not
1.360 + * other threads are currently waiting.
1.361 + * This "barging" behavior can be useful in certain
1.362 + * circumstances, even though it breaks fairness. If you want to honor
1.363 + * the fairness setting, then use
1.364 + * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
1.365 + * which is almost equivalent (it also detects interruption).
1.366 + *
1.367 + * @return {@code true} if a permit was acquired and {@code false}
1.368 + * otherwise
1.369 + */
1.370 + public boolean tryAcquire() {
1.371 + return sync.nonfairTryAcquireShared(1) >= 0;
1.372 + }
1.373 +
1.374 + /**
1.375 + * Acquires a permit from this semaphore, if one becomes available
1.376 + * within the given waiting time and the current thread has not
1.377 + * been {@linkplain Thread#interrupt interrupted}.
1.378 + *
1.379 + * <p>Acquires a permit, if one is available and returns immediately,
1.380 + * with the value {@code true},
1.381 + * reducing the number of available permits by one.
1.382 + *
1.383 + * <p>If no permit is available then the current thread becomes
1.384 + * disabled for thread scheduling purposes and lies dormant until
1.385 + * one of three things happens:
1.386 + * <ul>
1.387 + * <li>Some other thread invokes the {@link #release} method for this
1.388 + * semaphore and the current thread is next to be assigned a permit; or
1.389 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
1.390 + * the current thread; or
1.391 + * <li>The specified waiting time elapses.
1.392 + * </ul>
1.393 + *
1.394 + * <p>If a permit is acquired then the value {@code true} is returned.
1.395 + *
1.396 + * <p>If the current thread:
1.397 + * <ul>
1.398 + * <li>has its interrupted status set on entry to this method; or
1.399 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
1.400 + * to acquire a permit,
1.401 + * </ul>
1.402 + * then {@link InterruptedException} is thrown and the current thread's
1.403 + * interrupted status is cleared.
1.404 + *
1.405 + * <p>If the specified waiting time elapses then the value {@code false}
1.406 + * is returned. If the time is less than or equal to zero, the method
1.407 + * will not wait at all.
1.408 + *
1.409 + * @param timeout the maximum time to wait for a permit
1.410 + * @param unit the time unit of the {@code timeout} argument
1.411 + * @return {@code true} if a permit was acquired and {@code false}
1.412 + * if the waiting time elapsed before a permit was acquired
1.413 + * @throws InterruptedException if the current thread is interrupted
1.414 + */
1.415 + public boolean tryAcquire(long timeout, TimeUnit unit)
1.416 + throws InterruptedException {
1.417 + return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
1.418 + }
1.419 +
1.420 + /**
1.421 + * Releases a permit, returning it to the semaphore.
1.422 + *
1.423 + * <p>Releases a permit, increasing the number of available permits by
1.424 + * one. If any threads are trying to acquire a permit, then one is
1.425 + * selected and given the permit that was just released. That thread
1.426 + * is (re)enabled for thread scheduling purposes.
1.427 + *
1.428 + * <p>There is no requirement that a thread that releases a permit must
1.429 + * have acquired that permit by calling {@link #acquire}.
1.430 + * Correct usage of a semaphore is established by programming convention
1.431 + * in the application.
1.432 + */
1.433 + public void release() {
1.434 + sync.releaseShared(1);
1.435 + }
1.436 +
1.437 + /**
1.438 + * Acquires the given number of permits from this semaphore,
1.439 + * blocking until all are available,
1.440 + * or the thread is {@linkplain Thread#interrupt interrupted}.
1.441 + *
1.442 + * <p>Acquires the given number of permits, if they are available,
1.443 + * and returns immediately, reducing the number of available permits
1.444 + * by the given amount.
1.445 + *
1.446 + * <p>If insufficient permits are available then the current thread becomes
1.447 + * disabled for thread scheduling purposes and lies dormant until
1.448 + * one of two things happens:
1.449 + * <ul>
1.450 + * <li>Some other thread invokes one of the {@link #release() release}
1.451 + * methods for this semaphore, the current thread is next to be assigned
1.452 + * permits and the number of available permits satisfies this request; or
1.453 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
1.454 + * the current thread.
1.455 + * </ul>
1.456 + *
1.457 + * <p>If the current thread:
1.458 + * <ul>
1.459 + * <li>has its interrupted status set on entry to this method; or
1.460 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
1.461 + * for a permit,
1.462 + * </ul>
1.463 + * then {@link InterruptedException} is thrown and the current thread's
1.464 + * interrupted status is cleared.
1.465 + * Any permits that were to be assigned to this thread are instead
1.466 + * assigned to other threads trying to acquire permits, as if
1.467 + * permits had been made available by a call to {@link #release()}.
1.468 + *
1.469 + * @param permits the number of permits to acquire
1.470 + * @throws InterruptedException if the current thread is interrupted
1.471 + * @throws IllegalArgumentException if {@code permits} is negative
1.472 + */
1.473 + public void acquire(int permits) throws InterruptedException {
1.474 + if (permits < 0) throw new IllegalArgumentException();
1.475 + sync.acquireSharedInterruptibly(permits);
1.476 + }
1.477 +
1.478 + /**
1.479 + * Acquires the given number of permits from this semaphore,
1.480 + * blocking until all are available.
1.481 + *
1.482 + * <p>Acquires the given number of permits, if they are available,
1.483 + * and returns immediately, reducing the number of available permits
1.484 + * by the given amount.
1.485 + *
1.486 + * <p>If insufficient permits are available then the current thread becomes
1.487 + * disabled for thread scheduling purposes and lies dormant until
1.488 + * some other thread invokes one of the {@link #release() release}
1.489 + * methods for this semaphore, the current thread is next to be assigned
1.490 + * permits and the number of available permits satisfies this request.
1.491 + *
1.492 + * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
1.493 + * while waiting for permits then it will continue to wait and its
1.494 + * position in the queue is not affected. When the thread does return
1.495 + * from this method its interrupt status will be set.
1.496 + *
1.497 + * @param permits the number of permits to acquire
1.498 + * @throws IllegalArgumentException if {@code permits} is negative
1.499 + *
1.500 + */
1.501 + public void acquireUninterruptibly(int permits) {
1.502 + if (permits < 0) throw new IllegalArgumentException();
1.503 + sync.acquireShared(permits);
1.504 + }
1.505 +
1.506 + /**
1.507 + * Acquires the given number of permits from this semaphore, only
1.508 + * if all are available at the time of invocation.
1.509 + *
1.510 + * <p>Acquires the given number of permits, if they are available, and
1.511 + * returns immediately, with the value {@code true},
1.512 + * reducing the number of available permits by the given amount.
1.513 + *
1.514 + * <p>If insufficient permits are available then this method will return
1.515 + * immediately with the value {@code false} and the number of available
1.516 + * permits is unchanged.
1.517 + *
1.518 + * <p>Even when this semaphore has been set to use a fair ordering
1.519 + * policy, a call to {@code tryAcquire} <em>will</em>
1.520 + * immediately acquire a permit if one is available, whether or
1.521 + * not other threads are currently waiting. This
1.522 + * "barging" behavior can be useful in certain
1.523 + * circumstances, even though it breaks fairness. If you want to
1.524 + * honor the fairness setting, then use {@link #tryAcquire(int,
1.525 + * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) }
1.526 + * which is almost equivalent (it also detects interruption).
1.527 + *
1.528 + * @param permits the number of permits to acquire
1.529 + * @return {@code true} if the permits were acquired and
1.530 + * {@code false} otherwise
1.531 + * @throws IllegalArgumentException if {@code permits} is negative
1.532 + */
1.533 + public boolean tryAcquire(int permits) {
1.534 + if (permits < 0) throw new IllegalArgumentException();
1.535 + return sync.nonfairTryAcquireShared(permits) >= 0;
1.536 + }
1.537 +
1.538 + /**
1.539 + * Acquires the given number of permits from this semaphore, if all
1.540 + * become available within the given waiting time and the current
1.541 + * thread has not been {@linkplain Thread#interrupt interrupted}.
1.542 + *
1.543 + * <p>Acquires the given number of permits, if they are available and
1.544 + * returns immediately, with the value {@code true},
1.545 + * reducing the number of available permits by the given amount.
1.546 + *
1.547 + * <p>If insufficient permits are available then
1.548 + * the current thread becomes disabled for thread scheduling
1.549 + * purposes and lies dormant until one of three things happens:
1.550 + * <ul>
1.551 + * <li>Some other thread invokes one of the {@link #release() release}
1.552 + * methods for this semaphore, the current thread is next to be assigned
1.553 + * permits and the number of available permits satisfies this request; or
1.554 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
1.555 + * the current thread; or
1.556 + * <li>The specified waiting time elapses.
1.557 + * </ul>
1.558 + *
1.559 + * <p>If the permits are acquired then the value {@code true} is returned.
1.560 + *
1.561 + * <p>If the current thread:
1.562 + * <ul>
1.563 + * <li>has its interrupted status set on entry to this method; or
1.564 + * <li>is {@linkplain Thread#interrupt interrupted} while waiting
1.565 + * to acquire the permits,
1.566 + * </ul>
1.567 + * then {@link InterruptedException} is thrown and the current thread's
1.568 + * interrupted status is cleared.
1.569 + * Any permits that were to be assigned to this thread, are instead
1.570 + * assigned to other threads trying to acquire permits, as if
1.571 + * the permits had been made available by a call to {@link #release()}.
1.572 + *
1.573 + * <p>If the specified waiting time elapses then the value {@code false}
1.574 + * is returned. If the time is less than or equal to zero, the method
1.575 + * will not wait at all. Any permits that were to be assigned to this
1.576 + * thread, are instead assigned to other threads trying to acquire
1.577 + * permits, as if the permits had been made available by a call to
1.578 + * {@link #release()}.
1.579 + *
1.580 + * @param permits the number of permits to acquire
1.581 + * @param timeout the maximum time to wait for the permits
1.582 + * @param unit the time unit of the {@code timeout} argument
1.583 + * @return {@code true} if all permits were acquired and {@code false}
1.584 + * if the waiting time elapsed before all permits were acquired
1.585 + * @throws InterruptedException if the current thread is interrupted
1.586 + * @throws IllegalArgumentException if {@code permits} is negative
1.587 + */
1.588 + public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
1.589 + throws InterruptedException {
1.590 + if (permits < 0) throw new IllegalArgumentException();
1.591 + return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
1.592 + }
1.593 +
1.594 + /**
1.595 + * Releases the given number of permits, returning them to the semaphore.
1.596 + *
1.597 + * <p>Releases the given number of permits, increasing the number of
1.598 + * available permits by that amount.
1.599 + * If any threads are trying to acquire permits, then one
1.600 + * is selected and given the permits that were just released.
1.601 + * If the number of available permits satisfies that thread's request
1.602 + * then that thread is (re)enabled for thread scheduling purposes;
1.603 + * otherwise the thread will wait until sufficient permits are available.
1.604 + * If there are still permits available
1.605 + * after this thread's request has been satisfied, then those permits
1.606 + * are assigned in turn to other threads trying to acquire permits.
1.607 + *
1.608 + * <p>There is no requirement that a thread that releases a permit must
1.609 + * have acquired that permit by calling {@link Semaphore#acquire acquire}.
1.610 + * Correct usage of a semaphore is established by programming convention
1.611 + * in the application.
1.612 + *
1.613 + * @param permits the number of permits to release
1.614 + * @throws IllegalArgumentException if {@code permits} is negative
1.615 + */
1.616 + public void release(int permits) {
1.617 + if (permits < 0) throw new IllegalArgumentException();
1.618 + sync.releaseShared(permits);
1.619 + }
1.620 +
1.621 + /**
1.622 + * Returns the current number of permits available in this semaphore.
1.623 + *
1.624 + * <p>This method is typically used for debugging and testing purposes.
1.625 + *
1.626 + * @return the number of permits available in this semaphore
1.627 + */
1.628 + public int availablePermits() {
1.629 + return sync.getPermits();
1.630 + }
1.631 +
1.632 + /**
1.633 + * Acquires and returns all permits that are immediately available.
1.634 + *
1.635 + * @return the number of permits acquired
1.636 + */
1.637 + public int drainPermits() {
1.638 + return sync.drainPermits();
1.639 + }
1.640 +
1.641 + /**
1.642 + * Shrinks the number of available permits by the indicated
1.643 + * reduction. This method can be useful in subclasses that use
1.644 + * semaphores to track resources that become unavailable. This
1.645 + * method differs from {@code acquire} in that it does not block
1.646 + * waiting for permits to become available.
1.647 + *
1.648 + * @param reduction the number of permits to remove
1.649 + * @throws IllegalArgumentException if {@code reduction} is negative
1.650 + */
1.651 + protected void reducePermits(int reduction) {
1.652 + if (reduction < 0) throw new IllegalArgumentException();
1.653 + sync.reducePermits(reduction);
1.654 + }
1.655 +
1.656 + /**
1.657 + * Returns {@code true} if this semaphore has fairness set true.
1.658 + *
1.659 + * @return {@code true} if this semaphore has fairness set true
1.660 + */
1.661 + public boolean isFair() {
1.662 + return sync instanceof FairSync;
1.663 + }
1.664 +
1.665 + /**
1.666 + * Queries whether any threads are waiting to acquire. Note that
1.667 + * because cancellations may occur at any time, a {@code true}
1.668 + * return does not guarantee that any other thread will ever
1.669 + * acquire. This method is designed primarily for use in
1.670 + * monitoring of the system state.
1.671 + *
1.672 + * @return {@code true} if there may be other threads waiting to
1.673 + * acquire the lock
1.674 + */
1.675 + public final boolean hasQueuedThreads() {
1.676 + return sync.hasQueuedThreads();
1.677 + }
1.678 +
1.679 + /**
1.680 + * Returns an estimate of the number of threads waiting to acquire.
1.681 + * The value is only an estimate because the number of threads may
1.682 + * change dynamically while this method traverses internal data
1.683 + * structures. This method is designed for use in monitoring of the
1.684 + * system state, not for synchronization control.
1.685 + *
1.686 + * @return the estimated number of threads waiting for this lock
1.687 + */
1.688 + public final int getQueueLength() {
1.689 + return sync.getQueueLength();
1.690 + }
1.691 +
1.692 + /**
1.693 + * Returns a collection containing threads that may be waiting to acquire.
1.694 + * Because the actual set of threads may change dynamically while
1.695 + * constructing this result, the returned collection is only a best-effort
1.696 + * estimate. The elements of the returned collection are in no particular
1.697 + * order. This method is designed to facilitate construction of
1.698 + * subclasses that provide more extensive monitoring facilities.
1.699 + *
1.700 + * @return the collection of threads
1.701 + */
1.702 + protected Collection<Thread> getQueuedThreads() {
1.703 + return sync.getQueuedThreads();
1.704 + }
1.705 +
1.706 + /**
1.707 + * Returns a string identifying this semaphore, as well as its state.
1.708 + * The state, in brackets, includes the String {@code "Permits ="}
1.709 + * followed by the number of permits.
1.710 + *
1.711 + * @return a string identifying this semaphore, as well as its state
1.712 + */
1.713 + public String toString() {
1.714 + return super.toString() + "[Permits = " + sync.getPermits() + "]";
1.715 + }
1.716 +}