rt/emul/compact/src/main/java/java/util/concurrent/Semaphore.java
branchjdk7-b147
changeset 1890 212417b74b72
     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 &quot;lock&quot; 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 &quot;barging&quot; 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 +     * &quot;barging&quot; 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 +}