1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is free software; you can redistribute it and/or modify it
529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * under the terms of the GNU General Public License version 2 only, as
629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * published by the Free Software Foundation.  Oracle designates this
729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * particular file as subject to the "Classpath" exception as provided
829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * by Oracle in the LICENSE file that accompanied this code.
929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
1029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is distributed in the hope that it will be useful, but WITHOUT
1129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * version 2 for more details (a copy is included in the LICENSE file that
1429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * accompanied this code).
1529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
1629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * You should have received a copy of the GNU General Public License version
1729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 2 along with this work; if not, write to the Free Software Foundation,
1829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
2029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * or visit www.oracle.com if you need additional information or have any
2229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * questions.
2329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer */
2429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer
2529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer/*
2629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This file is available under and governed by the GNU General Public
2729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * License version 2 only, as published by the Free Software Foundation.
2829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * However, the following notice accompanied the original version of this
2929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * file:
3029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at
33a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent;
37edf43d27e240d82106f39ae91404963c23987234Narayan Kamath
3891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.Collection;
3991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.concurrent.locks.AbstractQueuedSynchronizer;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A counting semaphore.  Conceptually, a semaphore maintains a set of
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * permits.  Each {@link #acquire} blocks if necessary until a permit is
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available, and then takes it.  Each {@link #release} adds a permit,
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * potentially releasing a blocking acquirer.
46bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * However, no actual permit objects are used; the {@code Semaphore} just
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * keeps a count of the number available and acts accordingly.
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>Semaphores are often used to restrict the number of threads than can
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access some (physical or logical) resource. For example, here is
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a class that uses a semaphore to control access to a pool of items:
52b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * <pre> {@code
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class Pool {
54bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *   private static final int MAX_AVAILABLE = 100;
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   public Object getItem() throws InterruptedException {
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     available.acquire();
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     return getNextAvailableItem();
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   public void putItem(Object x) {
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     if (markAsUnused(x))
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       available.release();
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   // Not a particularly efficient data structure; just for demo
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   protected Object[] items = ... whatever kinds of items being managed
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   protected boolean[] used = new boolean[MAX_AVAILABLE];
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   protected synchronized Object getNextAvailableItem() {
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     for (int i = 0; i < MAX_AVAILABLE; ++i) {
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       if (!used[i]) {
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *          used[i] = true;
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *          return items[i];
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       }
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     }
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     return null; // not reached
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   protected synchronized boolean markAsUnused(Object item) {
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     for (int i = 0; i < MAX_AVAILABLE; ++i) {
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       if (item == items[i]) {
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *          if (used[i]) {
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *            used[i] = false;
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *            return true;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *          } else
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *            return false;
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       }
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     }
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     return false;
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *   }
94a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * }}</pre>
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>Before obtaining an item each thread must acquire a permit from
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the semaphore, guaranteeing that an item is available for use. When
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the thread has finished with the item it is returned back to the
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * pool and a permit is returned to the semaphore, allowing another
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread to acquire that item.  Note that no synchronization lock is
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * held when {@link #acquire} is called as that would prevent an item
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from being returned to the pool.  The semaphore encapsulates the
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * synchronization needed to restrict access to the pool, separately
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from any synchronization needed to maintain the consistency of the
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * pool itself.
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>A semaphore initialized to one, and which is used such that it
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only has at most one permit available, can serve as a mutual
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exclusion lock.  This is more commonly known as a <em>binary
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * semaphore</em>, because it only has two states: one permit
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * available, or zero permits available.  When used in this way, the
11291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * binary semaphore has the property (unlike many {@link java.util.concurrent.locks.Lock}
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementations), that the &quot;lock&quot; can be released by a
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thread other than the owner (as semaphores have no notion of
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ownership).  This can be useful in some specialized contexts, such
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * as deadlock recovery.
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <p>The constructor for this class optionally accepts a
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <em>fairness</em> parameter. When set false, this class makes no
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * guarantees about the order in which threads acquire permits. In
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * particular, <em>barging</em> is permitted, that is, a thread
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invoking {@link #acquire} can be allocated a permit ahead of a
123bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * thread that has been waiting - logically the new thread places itself at
124bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the head of the queue of waiting threads. When fairness is set true, the
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * semaphore guarantees that threads invoking any of the {@link
126bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * #acquire() acquire} methods are selected to obtain permits in the order in
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * which their invocation of those methods was processed
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (first-in-first-out; FIFO). Note that FIFO ordering necessarily
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * applies to specific internal points of execution within these
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * methods.  So, it is possible for one thread to invoke
131bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code acquire} before another, but reach the ordering point after
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the other, and similarly upon return from the method.
133bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
134bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * honor the fairness setting, but will take any permits that are
135bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * available.
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>Generally, semaphores used to control resource access should be
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * initialized as fair, to ensure that no thread is starved out from
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * accessing a resource. When using semaphores for other kinds of
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * synchronization control, the throughput advantages of non-fair
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ordering often outweigh fairness considerations.
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>This class also provides convenience methods to {@link
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * #acquire(int) acquire} and {@link #release(int) release} multiple
145b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * permits at a time. These methods are generally more efficient and
146b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * effective than loops. However, they do not establish any preference
147b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * order. For example, if thread A invokes {@code s.acquire(3}) and
148b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * thread B invokes {@code s.acquire(2)}, and two permits become
149b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * available, then there is no guarantee that thread B will obtain
150b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * them unless its acquire came first and Semaphore {@code s} is in
151b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak * fair mode.
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
153bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>Memory consistency effects: Actions in a thread prior to calling
154bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * a "release" method such as {@code release()}
155bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
156bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * actions following a successful "acquire" method such as {@code acquire()}
157bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * in another thread.
158bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Semaphore implements java.io.Serializable {
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = -3222578661600680210L;
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /** All mechanics via AbstractQueuedSynchronizer subclass */
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Sync sync;
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Synchronization implementation for semaphore.  Uses AQS state
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to represent permits. Subclassed into fair and nonfair
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * versions.
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    abstract static class Sync extends AbstractQueuedSynchronizer {
173bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private static final long serialVersionUID = 1192457210091910933L;
174bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Sync(int permits) {
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            setState(permits);
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
178bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final int getPermits() {
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return getState();
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final int nonfairTryAcquireShared(int acquires) {
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (;;) {
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int available = getState();
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int remaining = available - acquires;
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (remaining < 0 ||
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    compareAndSetState(available, remaining))
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return remaining;
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
192bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected final boolean tryReleaseShared(int releases) {
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (;;) {
1958eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                int current = getState();
1968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                int next = current + releases;
1978eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (next < current) // overflow
1988eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    throw new Error("Maximum permit count exceeded");
1998eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (compareAndSetState(current, next))
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return true;
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final void reducePermits(int reductions) {
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (;;) {
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int current = getState();
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int next = current - reductions;
2088eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                if (next > current) // underflow
2098eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson                    throw new Error("Permit count underflow");
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (compareAndSetState(current, next))
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return;
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        final int drainPermits() {
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (;;) {
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int current = getState();
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (current == 0 || compareAndSetState(current, 0))
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return current;
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * NonFair version
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2278eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    static final class NonfairSync extends Sync {
228bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private static final long serialVersionUID = -2694183684443567898L;
229bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        NonfairSync(int permits) {
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(permits);
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
233bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected int tryAcquireShared(int acquires) {
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return nonfairTryAcquireShared(acquires);
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Fair version
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson    static final class FairSync extends Sync {
243bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        private static final long serialVersionUID = 2014338818796000944L;
244bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        FairSync(int permits) {
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            super(permits);
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
248bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        protected int tryAcquireShared(int acquires) {
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (;;) {
2516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson                if (hasQueuedPredecessors())
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return -1;
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int available = getState();
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int remaining = available - acquires;
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (remaining < 0 ||
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    compareAndSetState(available, remaining))
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return remaining;
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
263bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a {@code Semaphore} with the given number of
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * permits and nonfair fairness setting.
265bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
266bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param permits the initial number of permits available.
267bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        This value may be negative, in which case releases
268bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        must occur before any acquires will be granted.
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
270bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public Semaphore(int permits) {
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sync = new NonfairSync(permits);
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
275bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a {@code Semaphore} with the given number of
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * permits and the given fairness setting.
277bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
278bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param permits the initial number of permits available.
279bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        This value may be negative, in which case releases
280bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        must occur before any acquires will be granted.
281bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param fair {@code true} if this semaphore will guarantee
282bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        first-in first-out granting of permits under contention,
283bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        else {@code false}
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
285bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public Semaphore(int permits, boolean fair) {
2868eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Acquires a permit from this semaphore, blocking until one is
291bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * available, or the thread is {@linkplain Thread#interrupt interrupted}.
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>Acquires a permit, if one is available and returns immediately,
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * reducing the number of available permits by one.
295bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If no permit is available then the current thread becomes
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * disabled for thread scheduling purposes and lies dormant until
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * one of two things happens:
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <ul>
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>Some other thread invokes the {@link #release} method for this
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * semaphore and the current thread is next to be assigned a permit; or
302bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
303bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the current thread.
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </ul>
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If the current thread:
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <ul>
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>has its interrupted status set on entry to this method; or
309bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * for a permit,
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </ul>
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then {@link InterruptedException} is thrown and the current thread's
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * interrupted status is cleared.
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InterruptedException if the current thread is interrupted
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void acquire() throws InterruptedException {
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sync.acquireSharedInterruptibly(1);
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Acquires a permit from this semaphore, blocking until one is
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * available.
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>Acquires a permit, if one is available and returns immediately,
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * reducing the number of available permits by one.
327bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If no permit is available then the current thread becomes
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * disabled for thread scheduling purposes and lies dormant until
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * some other thread invokes the {@link #release} method for this
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * semaphore and the current thread is next to be assigned a permit.
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
333bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
334bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * while waiting for a permit then it will continue to wait, but the
335bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * time at which the thread is assigned a permit may change compared to
336bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the time it would have received the permit had no interruption
337bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * occurred.  When the thread does return from this method its interrupt
338bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * status will be set.
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void acquireUninterruptibly() {
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sync.acquireShared(1);
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
345bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Acquires a permit from this semaphore, only if one is available at the
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * time of invocation.
347bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>Acquires a permit, if one is available and returns immediately,
349bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * with the value {@code true},
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * reducing the number of available permits by one.
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If no permit is available then this method will return
353bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * immediately with the value {@code false}.
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>Even when this semaphore has been set to use a
356bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * fair ordering policy, a call to {@code tryAcquire()} <em>will</em>
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * immediately acquire a permit if one is available, whether or not
358bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * other threads are currently waiting.
359bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * This &quot;barging&quot; behavior can be useful in certain
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * circumstances, even though it breaks fairness. If you want to honor
361bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the fairness setting, then use
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * which is almost equivalent (it also detects interruption).
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
365bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return {@code true} if a permit was acquired and {@code false}
366bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         otherwise
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean tryAcquire() {
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.nonfairTryAcquireShared(1) >= 0;
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
373bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Acquires a permit from this semaphore, if one becomes available
374bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * within the given waiting time and the current thread has not
375bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * been {@linkplain Thread#interrupt interrupted}.
376bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>Acquires a permit, if one is available and returns immediately,
378bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * with the value {@code true},
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * reducing the number of available permits by one.
380bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
381bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If no permit is available then the current thread becomes
382bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * disabled for thread scheduling purposes and lies dormant until
383bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * one of three things happens:
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <ul>
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>Some other thread invokes the {@link #release} method for this
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * semaphore and the current thread is next to be assigned a permit; or
387bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
388bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the current thread; or
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>The specified waiting time elapses.
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </ul>
391bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
392bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If a permit is acquired then the value {@code true} is returned.
393bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If the current thread:
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <ul>
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>has its interrupted status set on entry to this method; or
397bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
398bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to acquire a permit,
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </ul>
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then {@link InterruptedException} is thrown and the current thread's
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * interrupted status is cleared.
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
403bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If the specified waiting time elapses then the value {@code false}
404bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * is returned.  If the time is less than or equal to zero, the method
405bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * will not wait at all.
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
407bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param timeout the maximum time to wait for a permit
408bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param unit the time unit of the {@code timeout} argument
409bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return {@code true} if a permit was acquired and {@code false}
410bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         if the waiting time elapsed before a permit was acquired
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InterruptedException if the current thread is interrupted
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
413bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean tryAcquire(long timeout, TimeUnit unit)
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws InterruptedException {
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Releases a permit, returning it to the semaphore.
420bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
421bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>Releases a permit, increasing the number of available permits by
422bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * one.  If any threads are trying to acquire a permit, then one is
423bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * selected and given the permit that was just released.  That thread
424bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * is (re)enabled for thread scheduling purposes.
425bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>There is no requirement that a thread that releases a permit must
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * have acquired that permit by calling {@link #acquire}.
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Correct usage of a semaphore is established by programming convention
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in the application.
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void release() {
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sync.releaseShared(1);
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
434bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
436bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Acquires the given number of permits from this semaphore,
437bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * blocking until all are available,
438bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * or the thread is {@linkplain Thread#interrupt interrupted}.
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>Acquires the given number of permits, if they are available,
441bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * and returns immediately, reducing the number of available permits
442b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * by the given amount. This method has the same effect as the
443b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * loop {@code for (int i = 0; i < permits; ++i) acquire();} except
444b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * that it atomically acquires the permits all at once:
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If insufficient permits are available then the current thread becomes
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * disabled for thread scheduling purposes and lies dormant until
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * one of two things happens:
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <ul>
450bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>Some other thread invokes one of the {@link #release() release}
451b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * methods for this semaphore and the current thread is next to be assigned
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * permits and the number of available permits satisfies this request; or
453bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
454bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the current thread.
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </ul>
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If the current thread:
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <ul>
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>has its interrupted status set on entry to this method; or
460bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * for a permit,
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </ul>
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then {@link InterruptedException} is thrown and the current thread's
464bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * interrupted status is cleared.
465bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Any permits that were to be assigned to this thread are instead
466bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * assigned to other threads trying to acquire permits, as if
467bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * permits had been made available by a call to {@link #release()}.
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param permits the number of permits to acquire
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InterruptedException if the current thread is interrupted
471bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if {@code permits} is negative
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void acquire(int permits) throws InterruptedException {
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (permits < 0) throw new IllegalArgumentException();
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sync.acquireSharedInterruptibly(permits);
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
479bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Acquires the given number of permits from this semaphore,
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * blocking until all are available.
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>Acquires the given number of permits, if they are available,
483bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * and returns immediately, reducing the number of available permits
484b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * by the given amount. This method has the same effect as the
485b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * loop {@code for (int i = 0; i < permits; ++i) acquireUninterruptibly();}
486b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * except that it atomically acquires the permits all at once:
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If insufficient permits are available then the current thread becomes
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * disabled for thread scheduling purposes and lies dormant until
490bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * some other thread invokes one of the {@link #release() release}
491b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * methods for this semaphore and the current thread is next to be assigned
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * permits and the number of available permits satisfies this request.
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
494bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
495bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * while waiting for permits then it will continue to wait and its
496bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * position in the queue is not affected.  When the thread does return
497bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * from this method its interrupt status will be set.
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param permits the number of permits to acquire
500bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if {@code permits} is negative
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void acquireUninterruptibly(int permits) {
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (permits < 0) throw new IllegalArgumentException();
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sync.acquireShared(permits);
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Acquires the given number of permits from this semaphore, only
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * if all are available at the time of invocation.
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
511bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>Acquires the given number of permits, if they are available, and
512bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * returns immediately, with the value {@code true},
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * reducing the number of available permits by the given amount.
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If insufficient permits are available then this method will return
516bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * immediately with the value {@code false} and the number of available
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * permits is unchanged.
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>Even when this semaphore has been set to use a fair ordering
520bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * policy, a call to {@code tryAcquire} <em>will</em>
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * immediately acquire a permit if one is available, whether or
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * not other threads are currently waiting.  This
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * &quot;barging&quot; behavior can be useful in certain
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * circumstances, even though it breaks fairness. If you want to
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * honor the fairness setting, then use {@link #tryAcquire(int,
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) }
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * which is almost equivalent (it also detects interruption).
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param permits the number of permits to acquire
530bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return {@code true} if the permits were acquired and
531bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         {@code false} otherwise
532bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if {@code permits} is negative
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean tryAcquire(int permits) {
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (permits < 0) throw new IllegalArgumentException();
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.nonfairTryAcquireShared(permits) >= 0;
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
540bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Acquires the given number of permits from this semaphore, if all
541bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * become available within the given waiting time and the current
542bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * thread has not been {@linkplain Thread#interrupt interrupted}.
543bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
544bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>Acquires the given number of permits, if they are available and
545bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * returns immediately, with the value {@code true},
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * reducing the number of available permits by the given amount.
547bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If insufficient permits are available then
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the current thread becomes disabled for thread scheduling
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * purposes and lies dormant until one of three things happens:
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <ul>
552bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>Some other thread invokes one of the {@link #release() release}
553b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * methods for this semaphore and the current thread is next to be assigned
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * permits and the number of available permits satisfies this request; or
555bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>Some other thread {@linkplain Thread#interrupt interrupts}
556bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the current thread; or
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>The specified waiting time elapses.
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </ul>
559bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
560bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If the permits are acquired then the value {@code true} is returned.
561bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>If the current thread:
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <ul>
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <li>has its interrupted status set on entry to this method; or
565bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <li>is {@linkplain Thread#interrupt interrupted} while waiting
566bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * to acquire the permits,
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </ul>
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then {@link InterruptedException} is thrown and the current thread's
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * interrupted status is cleared.
570bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Any permits that were to be assigned to this thread, are instead
571bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * assigned to other threads trying to acquire permits, as if
572bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the permits had been made available by a call to {@link #release()}.
573bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
574bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If the specified waiting time elapses then the value {@code false}
575bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * is returned.  If the time is less than or equal to zero, the method
576bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * will not wait at all.  Any permits that were to be assigned to this
577bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * thread, are instead assigned to other threads trying to acquire
578bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * permits, as if the permits had been made available by a call to
579bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@link #release()}.
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param permits the number of permits to acquire
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout the maximum time to wait for the permits
583bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param unit the time unit of the {@code timeout} argument
584bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return {@code true} if all permits were acquired and {@code false}
585bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         if the waiting time elapsed before all permits were acquired
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InterruptedException if the current thread is interrupted
587bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if {@code permits} is negative
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        throws InterruptedException {
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (permits < 0) throw new IllegalArgumentException();
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Releases the given number of permits, returning them to the semaphore.
597bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
598bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>Releases the given number of permits, increasing the number of
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * available permits by that amount.
600b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * If any threads are trying to acquire permits, then one thread
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is selected and given the permits that were just released.
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If the number of available permits satisfies that thread's request
603bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * then that thread is (re)enabled for thread scheduling purposes;
604bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * otherwise the thread will wait until sufficient permits are available.
605bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * If there are still permits available
606bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * after this thread's request has been satisfied, then those permits
607bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * are assigned in turn to other threads trying to acquire permits.
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>There is no requirement that a thread that releases a permit must
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * have acquired that permit by calling {@link Semaphore#acquire acquire}.
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Correct usage of a semaphore is established by programming convention
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in the application.
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param permits the number of permits to release
615bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if {@code permits} is negative
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void release(int permits) {
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (permits < 0) throw new IllegalArgumentException();
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sync.releaseShared(permits);
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the current number of permits available in this semaphore.
624bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>This method is typically used for debugging and testing purposes.
626bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
627bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the number of permits available in this semaphore
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int availablePermits() {
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.getPermits();
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
634bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Acquires and returns all permits that are immediately available.
635bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
636bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the number of permits acquired
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int drainPermits() {
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.drainPermits();
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Shrinks the number of available permits by the indicated
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * reduction. This method can be useful in subclasses that use
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * semaphores to track resources that become unavailable. This
646bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * method differs from {@code acquire} in that it does not block
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * waiting for permits to become available.
648bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param reduction the number of permits to remove
650bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws IllegalArgumentException if {@code reduction} is negative
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void reducePermits(int reduction) {
653bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (reduction < 0) throw new IllegalArgumentException();
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        sync.reducePermits(reduction);
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
658bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns {@code true} if this semaphore has fairness set true.
659bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
660bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return {@code true} if this semaphore has fairness set true
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isFair() {
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync instanceof FairSync;
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Queries whether any threads are waiting to acquire. Note that
668bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * because cancellations may occur at any time, a {@code true}
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * return does not guarantee that any other thread will ever
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * acquire.  This method is designed primarily for use in
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * monitoring of the system state.
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
673bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return {@code true} if there may be other threads waiting to
674bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         acquire the lock
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
676bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public final boolean hasQueuedThreads() {
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.hasQueuedThreads();
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
681bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns an estimate of the number of threads waiting to acquire.
682bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The value is only an estimate because the number of threads may
683bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * change dynamically while this method traverses internal data
684b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * structures.  This method is designed for use in monitoring
685bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * system state, not for synchronization control.
686bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the estimated number of threads waiting for this lock
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int getQueueLength() {
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.getQueueLength();
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
694bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns a collection containing threads that may be waiting to acquire.
695bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Because the actual set of threads may change dynamically while
696bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * constructing this result, the returned collection is only a best-effort
697bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * estimate.  The elements of the returned collection are in no particular
698bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * order.  This method is designed to facilitate construction of
699bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * subclasses that provide more extensive monitoring facilities.
700bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the collection of threads
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Collection<Thread> getQueuedThreads() {
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return sync.getQueuedThreads();
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string identifying this semaphore, as well as its state.
709bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The state, in brackets, includes the String {@code "Permits ="}
710bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * followed by the number of permits.
711bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
712bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return a string identifying this semaphore, as well as its state
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return super.toString() + "[Permits = " + sync.getPermits() + "]";
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
718