rt/emul/compact/src/main/java/java/util/concurrent/locks/ReentrantLock.java
branchjdk7-b147
changeset 1890 212417b74b72
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/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 &quot;barging&quot; 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 +}