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