1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantLock.java Sat Mar 19 10:46:31 2016 +0100
1.3 @@ -0,0 +1,770 @@
1.4 +/*
1.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.6 + *
1.7 + * This code is free software; you can redistribute it and/or modify it
1.8 + * under the terms of the GNU General Public License version 2 only, as
1.9 + * published by the Free Software Foundation. Oracle designates this
1.10 + * particular file as subject to the "Classpath" exception as provided
1.11 + * by Oracle in the LICENSE file that accompanied this code.
1.12 + *
1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.16 + * version 2 for more details (a copy is included in the LICENSE file that
1.17 + * accompanied this code).
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License version
1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.22 + *
1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.24 + * or visit www.oracle.com if you need additional information or have any
1.25 + * questions.
1.26 + */
1.27 +
1.28 +/*
1.29 + * This file is available under and governed by the GNU General Public
1.30 + * License version 2 only, as published by the Free Software Foundation.
1.31 + * However, the following notice accompanied the original version of this
1.32 + * file:
1.33 + *
1.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
1.35 + * Expert Group and released to the public domain, as explained at
1.36 + * http://creativecommons.org/publicdomain/zero/1.0/
1.37 + */
1.38 +
1.39 +package java.util.concurrent.locks;
1.40 +import java.util.*;
1.41 +import java.util.concurrent.*;
1.42 +import java.util.concurrent.atomic.*;
1.43 +
1.44 +/**
1.45 + * A reentrant mutual exclusion {@link Lock} with the same basic
1.46 + * behavior and semantics as the implicit monitor lock accessed using
1.47 + * {@code synchronized} methods and statements, but with extended
1.48 + * capabilities.
1.49 + *
1.50 + * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
1.51 + * successfully locking, but not yet unlocking it. A thread invoking
1.52 + * {@code lock} will return, successfully acquiring the lock, when
1.53 + * the lock is not owned by another thread. The method will return
1.54 + * immediately if the current thread already owns the lock. This can
1.55 + * be checked using methods {@link #isHeldByCurrentThread}, and {@link
1.56 + * #getHoldCount}.
1.57 + *
1.58 + * <p>The constructor for this class accepts an optional
1.59 + * <em>fairness</em> parameter. When set {@code true}, under
1.60 + * contention, locks favor granting access to the longest-waiting
1.61 + * thread. Otherwise this lock does not guarantee any particular
1.62 + * access order. Programs using fair locks accessed by many threads
1.63 + * may display lower overall throughput (i.e., are slower; often much
1.64 + * slower) than those using the default setting, but have smaller
1.65 + * variances in times to obtain locks and guarantee lack of
1.66 + * starvation. Note however, that fairness of locks does not guarantee
1.67 + * fairness of thread scheduling. Thus, one of many threads using a
1.68 + * fair lock may obtain it multiple times in succession while other
1.69 + * active threads are not progressing and not currently holding the
1.70 + * lock.
1.71 + * Also note that the untimed {@link #tryLock() tryLock} method does not
1.72 + * honor the fairness setting. It will succeed if the lock
1.73 + * is available even if other threads are waiting.
1.74 + *
1.75 + * <p>It is recommended practice to <em>always</em> immediately
1.76 + * follow a call to {@code lock} with a {@code try} block, most
1.77 + * typically in a before/after construction such as:
1.78 + *
1.79 + * <pre>
1.80 + * class X {
1.81 + * private final ReentrantLock lock = new ReentrantLock();
1.82 + * // ...
1.83 + *
1.84 + * public void m() {
1.85 + * lock.lock(); // block until condition holds
1.86 + * try {
1.87 + * // ... method body
1.88 + * } finally {
1.89 + * lock.unlock()
1.90 + * }
1.91 + * }
1.92 + * }
1.93 + * </pre>
1.94 + *
1.95 + * <p>In addition to implementing the {@link Lock} interface, this
1.96 + * class defines methods {@code isLocked} and
1.97 + * {@code getLockQueueLength}, as well as some associated
1.98 + * {@code protected} access methods that may be useful for
1.99 + * instrumentation and monitoring.
1.100 + *
1.101 + * <p>Serialization of this class behaves in the same way as built-in
1.102 + * locks: a deserialized lock is in the unlocked state, regardless of
1.103 + * its state when serialized.
1.104 + *
1.105 + * <p>This lock supports a maximum of 2147483647 recursive locks by
1.106 + * the same thread. Attempts to exceed this limit result in
1.107 + * {@link Error} throws from locking methods.
1.108 + *
1.109 + * @since 1.5
1.110 + * @author Doug Lea
1.111 + */
1.112 +public class ReentrantLock implements Lock, java.io.Serializable {
1.113 + private static final long serialVersionUID = 7373984872572414699L;
1.114 + /** Synchronizer providing all implementation mechanics */
1.115 + private final Sync sync;
1.116 +
1.117 + /**
1.118 + * Base of synchronization control for this lock. Subclassed
1.119 + * into fair and nonfair versions below. Uses AQS state to
1.120 + * represent the number of holds on the lock.
1.121 + */
1.122 + abstract static class Sync extends AbstractQueuedSynchronizer {
1.123 + private static final long serialVersionUID = -5179523762034025860L;
1.124 +
1.125 + /**
1.126 + * Performs {@link Lock#lock}. The main reason for subclassing
1.127 + * is to allow fast path for nonfair version.
1.128 + */
1.129 + abstract void lock();
1.130 +
1.131 + /**
1.132 + * Performs non-fair tryLock. tryAcquire is
1.133 + * implemented in subclasses, but both need nonfair
1.134 + * try for trylock method.
1.135 + */
1.136 + final boolean nonfairTryAcquire(int acquires) {
1.137 + final Thread current = Thread.currentThread();
1.138 + int c = getState();
1.139 + if (c == 0) {
1.140 + if (compareAndSetState(0, acquires)) {
1.141 + setExclusiveOwnerThread(current);
1.142 + return true;
1.143 + }
1.144 + }
1.145 + else if (current == getExclusiveOwnerThread()) {
1.146 + int nextc = c + acquires;
1.147 + if (nextc < 0) // overflow
1.148 + throw new Error("Maximum lock count exceeded");
1.149 + setState(nextc);
1.150 + return true;
1.151 + }
1.152 + return false;
1.153 + }
1.154 +
1.155 + protected final boolean tryRelease(int releases) {
1.156 + int c = getState() - releases;
1.157 + if (Thread.currentThread() != getExclusiveOwnerThread())
1.158 + throw new IllegalMonitorStateException();
1.159 + boolean free = false;
1.160 + if (c == 0) {
1.161 + free = true;
1.162 + setExclusiveOwnerThread(null);
1.163 + }
1.164 + setState(c);
1.165 + return free;
1.166 + }
1.167 +
1.168 + protected final boolean isHeldExclusively() {
1.169 + // While we must in general read state before owner,
1.170 + // we don't need to do so to check if current thread is owner
1.171 + return getExclusiveOwnerThread() == Thread.currentThread();
1.172 + }
1.173 +
1.174 + final ConditionObject newCondition() {
1.175 + return new ConditionObject();
1.176 + }
1.177 +
1.178 + // Methods relayed from outer class
1.179 +
1.180 + final Thread getOwner() {
1.181 + return getState() == 0 ? null : getExclusiveOwnerThread();
1.182 + }
1.183 +
1.184 + final int getHoldCount() {
1.185 + return isHeldExclusively() ? getState() : 0;
1.186 + }
1.187 +
1.188 + final boolean isLocked() {
1.189 + return getState() != 0;
1.190 + }
1.191 +
1.192 + /**
1.193 + * Reconstitutes this lock instance from a stream.
1.194 + * @param s the stream
1.195 + */
1.196 + private void readObject(java.io.ObjectInputStream s)
1.197 + throws java.io.IOException, ClassNotFoundException {
1.198 + s.defaultReadObject();
1.199 + setState(0); // reset to unlocked state
1.200 + }
1.201 + }
1.202 +
1.203 + /**
1.204 + * Sync object for non-fair locks
1.205 + */
1.206 + static final class NonfairSync extends Sync {
1.207 + private static final long serialVersionUID = 7316153563782823691L;
1.208 +
1.209 + /**
1.210 + * Performs lock. Try immediate barge, backing up to normal
1.211 + * acquire on failure.
1.212 + */
1.213 + final void lock() {
1.214 + if (compareAndSetState(0, 1))
1.215 + setExclusiveOwnerThread(Thread.currentThread());
1.216 + else
1.217 + acquire(1);
1.218 + }
1.219 +
1.220 + protected final boolean tryAcquire(int acquires) {
1.221 + return nonfairTryAcquire(acquires);
1.222 + }
1.223 + }
1.224 +
1.225 + /**
1.226 + * Sync object for fair locks
1.227 + */
1.228 + static final class FairSync extends Sync {
1.229 + private static final long serialVersionUID = -3000897897090466540L;
1.230 +
1.231 + final void lock() {
1.232 + acquire(1);
1.233 + }
1.234 +
1.235 + /**
1.236 + * Fair version of tryAcquire. Don't grant access unless
1.237 + * recursive call or no waiters or is first.
1.238 + */
1.239 + protected final boolean tryAcquire(int acquires) {
1.240 + final Thread current = Thread.currentThread();
1.241 + int c = getState();
1.242 + if (c == 0) {
1.243 + if (!hasQueuedPredecessors() &&
1.244 + compareAndSetState(0, acquires)) {
1.245 + setExclusiveOwnerThread(current);
1.246 + return true;
1.247 + }
1.248 + }
1.249 + else if (current == getExclusiveOwnerThread()) {
1.250 + int nextc = c + acquires;
1.251 + if (nextc < 0)
1.252 + throw new Error("Maximum lock count exceeded");
1.253 + setState(nextc);
1.254 + return true;
1.255 + }
1.256 + return false;
1.257 + }
1.258 + }
1.259 +
1.260 + /**
1.261 + * Creates an instance of {@code ReentrantLock}.
1.262 + * This is equivalent to using {@code ReentrantLock(false)}.
1.263 + */
1.264 + public ReentrantLock() {
1.265 + sync = new NonfairSync();
1.266 + }
1.267 +
1.268 + /**
1.269 + * Creates an instance of {@code ReentrantLock} with the
1.270 + * given fairness policy.
1.271 + *
1.272 + * @param fair {@code true} if this lock should use a fair ordering policy
1.273 + */
1.274 + public ReentrantLock(boolean fair) {
1.275 + sync = fair ? new FairSync() : new NonfairSync();
1.276 + }
1.277 +
1.278 + /**
1.279 + * Acquires the lock.
1.280 + *
1.281 + * <p>Acquires the lock if it is not held by another thread and returns
1.282 + * immediately, setting the lock hold count to one.
1.283 + *
1.284 + * <p>If the current thread already holds the lock then the hold
1.285 + * count is incremented by one and the method returns immediately.
1.286 + *
1.287 + * <p>If the lock is held by another thread then the
1.288 + * current thread becomes disabled for thread scheduling
1.289 + * purposes and lies dormant until the lock has been acquired,
1.290 + * at which time the lock hold count is set to one.
1.291 + */
1.292 + public void lock() {
1.293 + sync.lock();
1.294 + }
1.295 +
1.296 + /**
1.297 + * Acquires the lock unless the current thread is
1.298 + * {@linkplain Thread#interrupt interrupted}.
1.299 + *
1.300 + * <p>Acquires the lock if it is not held by another thread and returns
1.301 + * immediately, setting the lock hold count to one.
1.302 + *
1.303 + * <p>If the current thread already holds this lock then the hold count
1.304 + * is incremented by one and the method returns immediately.
1.305 + *
1.306 + * <p>If the lock is held by another thread then the
1.307 + * current thread becomes disabled for thread scheduling
1.308 + * purposes and lies dormant until one of two things happens:
1.309 + *
1.310 + * <ul>
1.311 + *
1.312 + * <li>The lock is acquired by the current thread; or
1.313 + *
1.314 + * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
1.315 + * current thread.
1.316 + *
1.317 + * </ul>
1.318 + *
1.319 + * <p>If the lock is acquired by the current thread then the lock hold
1.320 + * count is set to one.
1.321 + *
1.322 + * <p>If the current thread:
1.323 + *
1.324 + * <ul>
1.325 + *
1.326 + * <li>has its interrupted status set on entry to this method; or
1.327 + *
1.328 + * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
1.329 + * the lock,
1.330 + *
1.331 + * </ul>
1.332 + *
1.333 + * then {@link InterruptedException} is thrown and the current thread's
1.334 + * interrupted status is cleared.
1.335 + *
1.336 + * <p>In this implementation, as this method is an explicit
1.337 + * interruption point, preference is given to responding to the
1.338 + * interrupt over normal or reentrant acquisition of the lock.
1.339 + *
1.340 + * @throws InterruptedException if the current thread is interrupted
1.341 + */
1.342 + public void lockInterruptibly() throws InterruptedException {
1.343 + sync.acquireInterruptibly(1);
1.344 + }
1.345 +
1.346 + /**
1.347 + * Acquires the lock only if it is not held by another thread at the time
1.348 + * of invocation.
1.349 + *
1.350 + * <p>Acquires the lock if it is not held by another thread and
1.351 + * returns immediately with the value {@code true}, setting the
1.352 + * lock hold count to one. Even when this lock has been set to use a
1.353 + * fair ordering policy, a call to {@code tryLock()} <em>will</em>
1.354 + * immediately acquire the lock if it is available, whether or not
1.355 + * other threads are currently waiting for the lock.
1.356 + * This "barging" behavior can be useful in certain
1.357 + * circumstances, even though it breaks fairness. If you want to honor
1.358 + * the fairness setting for this lock, then use
1.359 + * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
1.360 + * which is almost equivalent (it also detects interruption).
1.361 + *
1.362 + * <p> If the current thread already holds this lock then the hold
1.363 + * count is incremented by one and the method returns {@code true}.
1.364 + *
1.365 + * <p>If the lock is held by another thread then this method will return
1.366 + * immediately with the value {@code false}.
1.367 + *
1.368 + * @return {@code true} if the lock was free and was acquired by the
1.369 + * current thread, or the lock was already held by the current
1.370 + * thread; and {@code false} otherwise
1.371 + */
1.372 + public boolean tryLock() {
1.373 + return sync.nonfairTryAcquire(1);
1.374 + }
1.375 +
1.376 + /**
1.377 + * Acquires the lock if it is not held by another thread within the given
1.378 + * waiting time and the current thread has not been
1.379 + * {@linkplain Thread#interrupt interrupted}.
1.380 + *
1.381 + * <p>Acquires the lock if it is not held by another thread and returns
1.382 + * immediately with the value {@code true}, setting the lock hold count
1.383 + * to one. If this lock has been set to use a fair ordering policy then
1.384 + * an available lock <em>will not</em> be acquired if any other threads
1.385 + * are waiting for the lock. This is in contrast to the {@link #tryLock()}
1.386 + * method. If you want a timed {@code tryLock} that does permit barging on
1.387 + * a fair lock then combine the timed and un-timed forms together:
1.388 + *
1.389 + * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
1.390 + * </pre>
1.391 + *
1.392 + * <p>If the current thread
1.393 + * already holds this lock then the hold count is incremented by one and
1.394 + * the method returns {@code true}.
1.395 + *
1.396 + * <p>If the lock is held by another thread then the
1.397 + * current thread becomes disabled for thread scheduling
1.398 + * purposes and lies dormant until one of three things happens:
1.399 + *
1.400 + * <ul>
1.401 + *
1.402 + * <li>The lock is acquired by the current thread; or
1.403 + *
1.404 + * <li>Some other thread {@linkplain Thread#interrupt interrupts}
1.405 + * the current thread; or
1.406 + *
1.407 + * <li>The specified waiting time elapses
1.408 + *
1.409 + * </ul>
1.410 + *
1.411 + * <p>If the lock is acquired then the value {@code true} is returned and
1.412 + * the lock hold count is set to one.
1.413 + *
1.414 + * <p>If the current thread:
1.415 + *
1.416 + * <ul>
1.417 + *
1.418 + * <li>has its interrupted status set on entry to this method; or
1.419 + *
1.420 + * <li>is {@linkplain Thread#interrupt interrupted} while
1.421 + * acquiring the lock,
1.422 + *
1.423 + * </ul>
1.424 + * then {@link InterruptedException} is thrown and the current thread's
1.425 + * interrupted status is cleared.
1.426 + *
1.427 + * <p>If the specified waiting time elapses then the value {@code false}
1.428 + * is returned. If the time is less than or equal to zero, the method
1.429 + * will not wait at all.
1.430 + *
1.431 + * <p>In this implementation, as this method is an explicit
1.432 + * interruption point, preference is given to responding to the
1.433 + * interrupt over normal or reentrant acquisition of the lock, and
1.434 + * over reporting the elapse of the waiting time.
1.435 + *
1.436 + * @param timeout the time to wait for the lock
1.437 + * @param unit the time unit of the timeout argument
1.438 + * @return {@code true} if the lock was free and was acquired by the
1.439 + * current thread, or the lock was already held by the current
1.440 + * thread; and {@code false} if the waiting time elapsed before
1.441 + * the lock could be acquired
1.442 + * @throws InterruptedException if the current thread is interrupted
1.443 + * @throws NullPointerException if the time unit is null
1.444 + *
1.445 + */
1.446 + public boolean tryLock(long timeout, TimeUnit unit)
1.447 + throws InterruptedException {
1.448 + return sync.tryAcquireNanos(1, unit.toNanos(timeout));
1.449 + }
1.450 +
1.451 + /**
1.452 + * Attempts to release this lock.
1.453 + *
1.454 + * <p>If the current thread is the holder of this lock then the hold
1.455 + * count is decremented. If the hold count is now zero then the lock
1.456 + * is released. If the current thread is not the holder of this
1.457 + * lock then {@link IllegalMonitorStateException} is thrown.
1.458 + *
1.459 + * @throws IllegalMonitorStateException if the current thread does not
1.460 + * hold this lock
1.461 + */
1.462 + public void unlock() {
1.463 + sync.release(1);
1.464 + }
1.465 +
1.466 + /**
1.467 + * Returns a {@link Condition} instance for use with this
1.468 + * {@link Lock} instance.
1.469 + *
1.470 + * <p>The returned {@link Condition} instance supports the same
1.471 + * usages as do the {@link Object} monitor methods ({@link
1.472 + * Object#wait() wait}, {@link Object#notify notify}, and {@link
1.473 + * Object#notifyAll notifyAll}) when used with the built-in
1.474 + * monitor lock.
1.475 + *
1.476 + * <ul>
1.477 + *
1.478 + * <li>If this lock is not held when any of the {@link Condition}
1.479 + * {@linkplain Condition#await() waiting} or {@linkplain
1.480 + * Condition#signal signalling} methods are called, then an {@link
1.481 + * IllegalMonitorStateException} is thrown.
1.482 + *
1.483 + * <li>When the condition {@linkplain Condition#await() waiting}
1.484 + * methods are called the lock is released and, before they
1.485 + * return, the lock is reacquired and the lock hold count restored
1.486 + * to what it was when the method was called.
1.487 + *
1.488 + * <li>If a thread is {@linkplain Thread#interrupt interrupted}
1.489 + * while waiting then the wait will terminate, an {@link
1.490 + * InterruptedException} will be thrown, and the thread's
1.491 + * interrupted status will be cleared.
1.492 + *
1.493 + * <li> Waiting threads are signalled in FIFO order.
1.494 + *
1.495 + * <li>The ordering of lock reacquisition for threads returning
1.496 + * from waiting methods is the same as for threads initially
1.497 + * acquiring the lock, which is in the default case not specified,
1.498 + * but for <em>fair</em> locks favors those threads that have been
1.499 + * waiting the longest.
1.500 + *
1.501 + * </ul>
1.502 + *
1.503 + * @return the Condition object
1.504 + */
1.505 + public Condition newCondition() {
1.506 + return sync.newCondition();
1.507 + }
1.508 +
1.509 + /**
1.510 + * Queries the number of holds on this lock by the current thread.
1.511 + *
1.512 + * <p>A thread has a hold on a lock for each lock action that is not
1.513 + * matched by an unlock action.
1.514 + *
1.515 + * <p>The hold count information is typically only used for testing and
1.516 + * debugging purposes. For example, if a certain section of code should
1.517 + * not be entered with the lock already held then we can assert that
1.518 + * fact:
1.519 + *
1.520 + * <pre>
1.521 + * class X {
1.522 + * ReentrantLock lock = new ReentrantLock();
1.523 + * // ...
1.524 + * public void m() {
1.525 + * assert lock.getHoldCount() == 0;
1.526 + * lock.lock();
1.527 + * try {
1.528 + * // ... method body
1.529 + * } finally {
1.530 + * lock.unlock();
1.531 + * }
1.532 + * }
1.533 + * }
1.534 + * </pre>
1.535 + *
1.536 + * @return the number of holds on this lock by the current thread,
1.537 + * or zero if this lock is not held by the current thread
1.538 + */
1.539 + public int getHoldCount() {
1.540 + return sync.getHoldCount();
1.541 + }
1.542 +
1.543 + /**
1.544 + * Queries if this lock is held by the current thread.
1.545 + *
1.546 + * <p>Analogous to the {@link Thread#holdsLock} method for built-in
1.547 + * monitor locks, this method is typically used for debugging and
1.548 + * testing. For example, a method that should only be called while
1.549 + * a lock is held can assert that this is the case:
1.550 + *
1.551 + * <pre>
1.552 + * class X {
1.553 + * ReentrantLock lock = new ReentrantLock();
1.554 + * // ...
1.555 + *
1.556 + * public void m() {
1.557 + * assert lock.isHeldByCurrentThread();
1.558 + * // ... method body
1.559 + * }
1.560 + * }
1.561 + * </pre>
1.562 + *
1.563 + * <p>It can also be used to ensure that a reentrant lock is used
1.564 + * in a non-reentrant manner, for example:
1.565 + *
1.566 + * <pre>
1.567 + * class X {
1.568 + * ReentrantLock lock = new ReentrantLock();
1.569 + * // ...
1.570 + *
1.571 + * public void m() {
1.572 + * assert !lock.isHeldByCurrentThread();
1.573 + * lock.lock();
1.574 + * try {
1.575 + * // ... method body
1.576 + * } finally {
1.577 + * lock.unlock();
1.578 + * }
1.579 + * }
1.580 + * }
1.581 + * </pre>
1.582 + *
1.583 + * @return {@code true} if current thread holds this lock and
1.584 + * {@code false} otherwise
1.585 + */
1.586 + public boolean isHeldByCurrentThread() {
1.587 + return sync.isHeldExclusively();
1.588 + }
1.589 +
1.590 + /**
1.591 + * Queries if this lock is held by any thread. This method is
1.592 + * designed for use in monitoring of the system state,
1.593 + * not for synchronization control.
1.594 + *
1.595 + * @return {@code true} if any thread holds this lock and
1.596 + * {@code false} otherwise
1.597 + */
1.598 + public boolean isLocked() {
1.599 + return sync.isLocked();
1.600 + }
1.601 +
1.602 + /**
1.603 + * Returns {@code true} if this lock has fairness set true.
1.604 + *
1.605 + * @return {@code true} if this lock has fairness set true
1.606 + */
1.607 + public final boolean isFair() {
1.608 + return sync instanceof FairSync;
1.609 + }
1.610 +
1.611 + /**
1.612 + * Returns the thread that currently owns this lock, or
1.613 + * {@code null} if not owned. When this method is called by a
1.614 + * thread that is not the owner, the return value reflects a
1.615 + * best-effort approximation of current lock status. For example,
1.616 + * the owner may be momentarily {@code null} even if there are
1.617 + * threads trying to acquire the lock but have not yet done so.
1.618 + * This method is designed to facilitate construction of
1.619 + * subclasses that provide more extensive lock monitoring
1.620 + * facilities.
1.621 + *
1.622 + * @return the owner, or {@code null} if not owned
1.623 + */
1.624 + protected Thread getOwner() {
1.625 + return sync.getOwner();
1.626 + }
1.627 +
1.628 + /**
1.629 + * Queries whether any threads are waiting to acquire this lock. Note that
1.630 + * because cancellations may occur at any time, a {@code true}
1.631 + * return does not guarantee that any other thread will ever
1.632 + * acquire this lock. This method is designed primarily for use in
1.633 + * monitoring of the system state.
1.634 + *
1.635 + * @return {@code true} if there may be other threads waiting to
1.636 + * acquire the lock
1.637 + */
1.638 + public final boolean hasQueuedThreads() {
1.639 + return sync.hasQueuedThreads();
1.640 + }
1.641 +
1.642 +
1.643 + /**
1.644 + * Queries whether the given thread is waiting to acquire this
1.645 + * lock. Note that because cancellations may occur at any time, a
1.646 + * {@code true} return does not guarantee that this thread
1.647 + * will ever acquire this lock. This method is designed primarily for use
1.648 + * in monitoring of the system state.
1.649 + *
1.650 + * @param thread the thread
1.651 + * @return {@code true} if the given thread is queued waiting for this lock
1.652 + * @throws NullPointerException if the thread is null
1.653 + */
1.654 + public final boolean hasQueuedThread(Thread thread) {
1.655 + return sync.isQueued(thread);
1.656 + }
1.657 +
1.658 +
1.659 + /**
1.660 + * Returns an estimate of the number of threads waiting to
1.661 + * acquire this lock. The value is only an estimate because the number of
1.662 + * threads may change dynamically while this method traverses
1.663 + * internal data structures. This method is designed for use in
1.664 + * monitoring of the system state, not for synchronization
1.665 + * control.
1.666 + *
1.667 + * @return the estimated number of threads waiting for this lock
1.668 + */
1.669 + public final int getQueueLength() {
1.670 + return sync.getQueueLength();
1.671 + }
1.672 +
1.673 + /**
1.674 + * Returns a collection containing threads that may be waiting to
1.675 + * acquire this lock. Because the actual set of threads may change
1.676 + * dynamically while constructing this result, the returned
1.677 + * collection is only a best-effort estimate. The elements of the
1.678 + * returned collection are in no particular order. This method is
1.679 + * designed to facilitate construction of subclasses that provide
1.680 + * more extensive monitoring facilities.
1.681 + *
1.682 + * @return the collection of threads
1.683 + */
1.684 + protected Collection<Thread> getQueuedThreads() {
1.685 + return sync.getQueuedThreads();
1.686 + }
1.687 +
1.688 + /**
1.689 + * Queries whether any threads are waiting on the given condition
1.690 + * associated with this lock. Note that because timeouts and
1.691 + * interrupts may occur at any time, a {@code true} return does
1.692 + * not guarantee that a future {@code signal} will awaken any
1.693 + * threads. This method is designed primarily for use in
1.694 + * monitoring of the system state.
1.695 + *
1.696 + * @param condition the condition
1.697 + * @return {@code true} if there are any waiting threads
1.698 + * @throws IllegalMonitorStateException if this lock is not held
1.699 + * @throws IllegalArgumentException if the given condition is
1.700 + * not associated with this lock
1.701 + * @throws NullPointerException if the condition is null
1.702 + */
1.703 + public boolean hasWaiters(Condition condition) {
1.704 + if (condition == null)
1.705 + throw new NullPointerException();
1.706 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
1.707 + throw new IllegalArgumentException("not owner");
1.708 + return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
1.709 + }
1.710 +
1.711 + /**
1.712 + * Returns an estimate of the number of threads waiting on the
1.713 + * given condition associated with this lock. Note that because
1.714 + * timeouts and interrupts may occur at any time, the estimate
1.715 + * serves only as an upper bound on the actual number of waiters.
1.716 + * This method is designed for use in monitoring of the system
1.717 + * state, not for synchronization control.
1.718 + *
1.719 + * @param condition the condition
1.720 + * @return the estimated number of waiting threads
1.721 + * @throws IllegalMonitorStateException if this lock is not held
1.722 + * @throws IllegalArgumentException if the given condition is
1.723 + * not associated with this lock
1.724 + * @throws NullPointerException if the condition is null
1.725 + */
1.726 + public int getWaitQueueLength(Condition condition) {
1.727 + if (condition == null)
1.728 + throw new NullPointerException();
1.729 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
1.730 + throw new IllegalArgumentException("not owner");
1.731 + return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
1.732 + }
1.733 +
1.734 + /**
1.735 + * Returns a collection containing those threads that may be
1.736 + * waiting on the given condition associated with this lock.
1.737 + * Because the actual set of threads may change dynamically while
1.738 + * constructing this result, the returned collection is only a
1.739 + * best-effort estimate. The elements of the returned collection
1.740 + * are in no particular order. This method is designed to
1.741 + * facilitate construction of subclasses that provide more
1.742 + * extensive condition monitoring facilities.
1.743 + *
1.744 + * @param condition the condition
1.745 + * @return the collection of threads
1.746 + * @throws IllegalMonitorStateException if this lock is not held
1.747 + * @throws IllegalArgumentException if the given condition is
1.748 + * not associated with this lock
1.749 + * @throws NullPointerException if the condition is null
1.750 + */
1.751 + protected Collection<Thread> getWaitingThreads(Condition condition) {
1.752 + if (condition == null)
1.753 + throw new NullPointerException();
1.754 + if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
1.755 + throw new IllegalArgumentException("not owner");
1.756 + return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
1.757 + }
1.758 +
1.759 + /**
1.760 + * Returns a string identifying this lock, as well as its lock state.
1.761 + * The state, in brackets, includes either the String {@code "Unlocked"}
1.762 + * or the String {@code "Locked by"} followed by the
1.763 + * {@linkplain Thread#getName name} of the owning thread.
1.764 + *
1.765 + * @return a string identifying this lock, as well as its lock state
1.766 + */
1.767 + public String toString() {
1.768 + Thread o = sync.getOwner();
1.769 + return super.toString() + ((o == null) ?
1.770 + "[Unlocked]" :
1.771 + "[Locked by thread " + o.getName() + "]");
1.772 + }
1.773 +}