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 "lock" 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 "barging" 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 * "barging" 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