001: /*
002: * Written by Doug Lea with assistance from members of JCP JSR-166
003: * Expert Group and released to the public domain, as explained at
004: * http://creativecommons.org/licenses/publicdomain
005: */
006:
007: package org.apache.beehive.netui.util.internal.concurrent;
008:
009: import java.util.*;
010:
011: /**
012: * A reentrant mutual exclusion {@link Lock} with the same basic
013: * behavior and semantics as the implicit monitor lock accessed using
014: * <tt>synchronized</tt> methods and statements, but with extended
015: * capabilities.
016: *
017: * <p> A <tt>ReentrantLock</tt> is <em>owned</em> by the thread last
018: * successfully locking, but not yet unlocking it. A thread invoking
019: * <tt>lock</tt> will return, successfully acquiring the lock, when
020: * the lock is not owned by another thread. The method will return
021: * immediately if the current thread already owns the lock. This can
022: * be checked using methods {@link #isHeldByCurrentThread}, and {@link
023: * #getHoldCount}.
024: *
025: * <p> The constructor for this class accepts an optional
026: * <em>fairness</em> parameter. When set <tt>true</tt>, under
027: * contention, locks favor granting access to the longest-waiting
028: * thread. Otherwise this lock does not guarantee any particular
029: * access order. Programs using fair locks accessed by many threads
030: * may display lower overall throughput (i.e., are slower; often much
031: * slower) than those using the default setting, but have smaller
032: * variances in times to obtain locks and guarantee lack of
033: * starvation. Note however, that fairness of locks does not guarantee
034: * fairness of thread scheduling. Thus, one of many threads using a
035: * fair lock may obtain it multiple times in succession while other
036: * active threads are not progressing and not currently holding the
037: * lock.
038: * Also note that the untimed {@link #tryLock() tryLock} method does not
039: * honor the fairness setting. It will succeed if the lock
040: * is available even if other threads are waiting.
041: *
042: * <p> It is recommended practice to <em>always</em> immediately
043: * follow a call to <tt>lock</tt> with a <tt>try</tt> block, most
044: * typically in a before/after construction such as:
045: *
046: * <pre>
047: * class X {
048: * private final ReentrantLock lock = new ReentrantLock();
049: * // ...
050: *
051: * public void m() {
052: * lock.lock(); // block until condition holds
053: * try {
054: * // ... method body
055: * } finally {
056: * lock.unlock()
057: * }
058: * }
059: * }
060: * </pre>
061: *
062: * <p>In addition to implementing the {@link Lock} interface, this
063: * class defines methods <tt>isLocked</tt> and
064: * <tt>getLockQueueLength</tt>, as well as some associated
065: * <tt>protected</tt> access methods that may be useful for
066: * instrumentation and monitoring.
067: *
068: * <p> Serialization of this class behaves in the same way as built-in
069: * locks: a deserialized lock is in the unlocked state, regardless of
070: * its state when serialized.
071: *
072: * <p> This lock supports a maximum of 2147483648 recursive locks by
073: * the same thread.
074: *
075: * @since 1.5
076: * @author Doug Lea
077: * @author Dawid Kurzyniec
078: */
079: class ReentrantLock implements Lock, java.io.Serializable,
080: CondVar.LockInfo {
081: private static final long serialVersionUID = 7373984872572414699L;
082:
083: private final Impl impl;
084:
085: static abstract class Impl {
086: protected Thread owner_ = null;
087: protected int holds_ = 0;
088:
089: protected Impl() {
090: }
091:
092: public abstract void lockInterruptibly()
093: throws InterruptedException;
094:
095: public boolean tryLock() {
096: Thread caller = Thread.currentThread();
097: synchronized (this ) {
098: if (owner_ == null) {
099: owner_ = caller;
100: holds_ = 1;
101: return true;
102: } else if (caller == owner_) {
103: ++holds_;
104: return true;
105: }
106: }
107: return false;
108: }
109:
110: public abstract boolean tryLock(long nanos)
111: throws InterruptedException;
112:
113: public abstract void unlock();
114:
115: public synchronized int getHoldCount() {
116: return isHeldByCurrentThread() ? holds_ : 0;
117: }
118:
119: public synchronized boolean isHeldByCurrentThread() {
120: return Thread.currentThread() == owner_;
121: }
122:
123: public synchronized boolean isLocked() {
124: return owner_ != null;
125: }
126:
127: public abstract boolean isFair();
128:
129: protected synchronized Thread getOwner() {
130: return owner_;
131: }
132:
133: public boolean hasQueuedThreads() {
134: throw new UnsupportedOperationException("Use FAIR version");
135: }
136:
137: public int getQueueLength() {
138: throw new UnsupportedOperationException("Use FAIR version");
139: }
140:
141: public Collection getQueuedThreads() {
142: throw new UnsupportedOperationException("Use FAIR version");
143: }
144:
145: public boolean isQueued(Thread thread) {
146: throw new UnsupportedOperationException("Use FAIR version");
147: }
148: }
149:
150: final static class NonfairImpl extends Impl implements
151: java.io.Serializable {
152:
153: NonfairImpl() {
154: }
155:
156: public void lockInterruptibly() throws InterruptedException {
157: if (Thread.interrupted())
158: throw new InterruptedException();
159: Thread caller = Thread.currentThread();
160: synchronized (this ) {
161: if (owner_ == null) {
162: owner_ = caller;
163: holds_ = 1;
164: return;
165: } else if (caller == owner_) {
166: ++holds_;
167: return;
168: } else {
169: try {
170: do {
171: wait();
172: } while (owner_ != null);
173: owner_ = caller;
174: holds_ = 1;
175: return;
176: } catch (InterruptedException ex) {
177: notify();
178: throw ex;
179: }
180: }
181: }
182: }
183:
184: public boolean tryLock(long nanos) throws InterruptedException {
185: if (Thread.interrupted())
186: throw new InterruptedException();
187: Thread caller = Thread.currentThread();
188:
189: synchronized (this ) {
190: if (owner_ == null) {
191: owner_ = caller;
192: holds_ = 1;
193: return true;
194: } else if (caller == owner_) {
195: ++holds_;
196: return true;
197: } else if (nanos <= 0)
198: return false;
199: else {
200: long deadline = Utils.nanoTime() + nanos;
201: try {
202: for (;;) {
203: TimeUnit.NANOSECONDS.timedWait(this , nanos);
204: if (caller == owner_) {
205: ++holds_;
206: return true;
207: } else if (owner_ == null) {
208: owner_ = caller;
209: holds_ = 1;
210: return true;
211: } else {
212: nanos = deadline - Utils.nanoTime();
213: if (nanos <= 0)
214: return false;
215: }
216: }
217: } catch (InterruptedException ex) {
218: notify();
219: throw ex;
220: }
221: }
222: }
223: }
224:
225: public synchronized void unlock() {
226: if (Thread.currentThread() != owner_)
227: throw new IllegalMonitorStateException("Not owner");
228:
229: if (--holds_ == 0) {
230: owner_ = null;
231: notify();
232: }
233: }
234:
235: public final boolean isFair() {
236: return false;
237: }
238: }
239:
240: final static class FairImpl extends Impl implements
241: WaitQueue.QueuedSync, java.io.Serializable {
242:
243: private final WaitQueue wq_ = new FIFOWaitQueue();
244:
245: FairImpl() {
246: }
247:
248: public synchronized boolean recheck(WaitQueue.WaitNode node) {
249: Thread caller = Thread.currentThread();
250: if (owner_ == null) {
251: owner_ = caller;
252: holds_ = 1;
253: return true;
254: } else if (caller == owner_) {
255: ++holds_;
256: return true;
257: }
258: wq_.insert(node);
259: return false;
260: }
261:
262: public synchronized void takeOver(WaitQueue.WaitNode node) {
263: // assert (holds_ == 1 && owner_ == Thread.currentThread()
264: owner_ = node.getOwner();
265: }
266:
267: public void lockInterruptibly() throws InterruptedException {
268: if (Thread.interrupted())
269: throw new InterruptedException();
270: Thread caller = Thread.currentThread();
271: synchronized (this ) {
272: if (owner_ == null) {
273: owner_ = caller;
274: holds_ = 1;
275: return;
276: } else if (caller == owner_) {
277: ++holds_;
278: return;
279: }
280: }
281: WaitQueue.WaitNode n = new WaitQueue.WaitNode();
282: n.doWait(this );
283: }
284:
285: public boolean tryLock(long nanos) throws InterruptedException {
286: if (Thread.interrupted())
287: throw new InterruptedException();
288: Thread caller = Thread.currentThread();
289: synchronized (this ) {
290: if (owner_ == null) {
291: owner_ = caller;
292: holds_ = 1;
293: return true;
294: } else if (caller == owner_) {
295: ++holds_;
296: return true;
297: }
298: }
299: WaitQueue.WaitNode n = new WaitQueue.WaitNode();
300: return n.doTimedWait(this , nanos);
301: }
302:
303: protected synchronized WaitQueue.WaitNode getSignallee(
304: Thread caller) {
305: if (caller != owner_)
306: throw new IllegalMonitorStateException("Not owner");
307: // assert (holds_ > 0)
308: if (holds_ >= 2) { // current thread will keep the lock
309: --holds_;
310: return null;
311: }
312: // assert (holds_ == 1)
313: WaitQueue.WaitNode w = wq_.extract();
314: if (w == null) { // if none, clear for new arrivals
315: owner_ = null;
316: holds_ = 0;
317: }
318: return w;
319: }
320:
321: public void unlock() {
322: Thread caller = Thread.currentThread();
323: for (;;) {
324: WaitQueue.WaitNode w = getSignallee(caller);
325: if (w == null)
326: return; // no one to signal
327: if (w.signal(this ))
328: return; // notify if still waiting, else skip
329: }
330: }
331:
332: public final boolean isFair() {
333: return true;
334: }
335:
336: public synchronized boolean hasQueuedThreads() {
337: return wq_.hasNodes();
338: }
339:
340: public synchronized int getQueueLength() {
341: return wq_.getLength();
342: }
343:
344: public synchronized Collection getQueuedThreads() {
345: return wq_.getWaitingThreads();
346: }
347:
348: public synchronized boolean isQueued(Thread thread) {
349: return wq_.isWaiting(thread);
350: }
351: }
352:
353: /**
354: * Creates an instance of <tt>ReentrantLock</tt>.
355: * This is equivalent to using <tt>ReentrantLock(false)</tt>.
356: */
357: public ReentrantLock() {
358: impl = new NonfairImpl();
359: }
360:
361: /**
362: * Creates an instance of <tt>ReentrantLock</tt> with the
363: * given fairness policy.
364: * @param fair true if this lock will be fair; else false
365: */
366: public ReentrantLock(boolean fair) {
367: impl = (fair) ? (Impl) new FairImpl() : new NonfairImpl();
368: }
369:
370: /**
371: * Acquires the lock.
372: *
373: * <p>Acquires the lock if it is not held by another thread and returns
374: * immediately, setting the lock hold count to one.
375: *
376: * <p>If the current thread
377: * already holds the lock then the hold count is incremented by one and
378: * the method returns immediately.
379: *
380: * <p>If the lock is held by another thread then the
381: * current thread becomes disabled for thread scheduling
382: * purposes and lies dormant until the lock has been acquired,
383: * at which time the lock hold count is set to one.
384: */
385: public void lock() {
386: boolean wasInterrupted = false;
387: while (true) {
388: try {
389: impl.lockInterruptibly();
390: if (wasInterrupted) {
391: Thread.currentThread().interrupt();
392: }
393: return;
394: } catch (InterruptedException e) {
395: wasInterrupted = true;
396: }
397: }
398: }
399:
400: /**
401: * Acquires the lock unless the current thread is
402: * {@link Thread#interrupt interrupted}.
403: *
404: * <p>Acquires the lock if it is not held by another thread and returns
405: * immediately, setting the lock hold count to one.
406: *
407: * <p>If the current thread already holds this lock then the hold count
408: * is incremented by one and the method returns immediately.
409: *
410: * <p>If the lock is held by another thread then the
411: * current thread becomes disabled for thread scheduling
412: * purposes and lies dormant until one of two things happens:
413: *
414: * <ul>
415: *
416: * <li>The lock is acquired by the current thread; or
417: *
418: * <li>Some other thread {@link Thread#interrupt interrupts} the current
419: * thread.
420: *
421: * </ul>
422: *
423: * <p>If the lock is acquired by the current thread then the lock hold
424: * count is set to one.
425: *
426: * <p>If the current thread:
427: *
428: * <ul>
429: *
430: * <li>has its interrupted status set on entry to this method; or
431: *
432: * <li>is {@link Thread#interrupt interrupted} while acquiring
433: * the lock,
434: *
435: * </ul>
436: *
437: * then {@link InterruptedException} is thrown and the current thread's
438: * interrupted status is cleared.
439: *
440: * <p>In this implementation, as this method is an explicit interruption
441: * point, preference is
442: * given to responding to the interrupt over normal or reentrant
443: * acquisition of the lock.
444: *
445: * @throws InterruptedException if the current thread is interrupted
446: */
447: public void lockInterruptibly() throws InterruptedException {
448: impl.lockInterruptibly();
449: }
450:
451: /**
452: * Acquires the lock only if it is not held by another thread at the time
453: * of invocation.
454: *
455: * <p>Acquires the lock if it is not held by another thread and
456: * returns immediately with the value <tt>true</tt>, setting the
457: * lock hold count to one. Even when this lock has been set to use a
458: * fair ordering policy, a call to <tt>tryLock()</tt> <em>will</em>
459: * immediately acquire the lock if it is available, whether or not
460: * other threads are currently waiting for the lock.
461: * This "barging" behavior can be useful in certain
462: * circumstances, even though it breaks fairness. If you want to honor
463: * the fairness setting for this lock, then use
464: * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
465: * which is almost equivalent (it also detects interruption).
466: *
467: * <p> If the current thread
468: * already holds this lock then the hold count is incremented by one and
469: * the method returns <tt>true</tt>.
470: *
471: * <p>If the lock is held by another thread then this method will return
472: * immediately with the value <tt>false</tt>.
473: *
474: * @return <tt>true</tt> if the lock was free and was acquired by the
475: * current thread, or the lock was already held by the current thread; and
476: * <tt>false</tt> otherwise.
477: */
478: public boolean tryLock() {
479: return impl.tryLock();
480: }
481:
482: /**
483: * Acquires the lock if it is not held by another thread within the given
484: * waiting time and the current thread has not been
485: * {@link Thread#interrupt interrupted}.
486: *
487: * <p>Acquires the lock if it is not held by another thread and returns
488: * immediately with the value <tt>true</tt>, setting the lock hold count
489: * to one. If this lock has been set to use a fair ordering policy then
490: * an available lock <em>will not</em> be acquired if any other threads
491: * are waiting for the lock. This is in contrast to the {@link #tryLock()}
492: * method. If you want a timed <tt>tryLock</tt> that does permit barging on
493: * a fair lock then combine the timed and un-timed forms together:
494: *
495: * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
496: * </pre>
497: *
498: * <p>If the current thread
499: * already holds this lock then the hold count is incremented by one and
500: * the method returns <tt>true</tt>.
501: *
502: * <p>If the lock is held by another thread then the
503: * current thread becomes disabled for thread scheduling
504: * purposes and lies dormant until one of three things happens:
505: *
506: * <ul>
507: *
508: * <li>The lock is acquired by the current thread; or
509: *
510: * <li>Some other thread {@link Thread#interrupt interrupts} the current
511: * thread; or
512: *
513: * <li>The specified waiting time elapses
514: *
515: * </ul>
516: *
517: * <p>If the lock is acquired then the value <tt>true</tt> is returned and
518: * the lock hold count is set to one.
519: *
520: * <p>If the current thread:
521: *
522: * <ul>
523: *
524: * <li>has its interrupted status set on entry to this method; or
525: *
526: * <li>is {@link Thread#interrupt interrupted} while acquiring
527: * the lock,
528: *
529: * </ul>
530: * then {@link InterruptedException} is thrown and the current thread's
531: * interrupted status is cleared.
532: *
533: * <p>If the specified waiting time elapses then the value <tt>false</tt>
534: * is returned.
535: * If the time is
536: * less than or equal to zero, the method will not wait at all.
537: *
538: * <p>In this implementation, as this method is an explicit interruption
539: * point, preference is
540: * given to responding to the interrupt over normal or reentrant
541: * acquisition of the lock, and over reporting the elapse of the waiting
542: * time.
543: *
544: * @param timeout the time to wait for the lock
545: * @param unit the time unit of the timeout argument
546: *
547: * @return <tt>true</tt> if the lock was free and was acquired by the
548: * current thread, or the lock was already held by the current thread; and
549: * <tt>false</tt> if the waiting time elapsed before the lock could be
550: * acquired.
551: *
552: * @throws InterruptedException if the current thread is interrupted
553: * @throws NullPointerException if unit is null
554: *
555: */
556: public boolean tryLock(long timeout, TimeUnit unit)
557: throws InterruptedException {
558: return impl.tryLock(unit.toNanos(timeout));
559: }
560:
561: /**
562: * Attempts to release this lock.
563: *
564: * <p>If the current thread is the
565: * holder of this lock then the hold count is decremented. If the
566: * hold count is now zero then the lock is released. If the
567: * current thread is not the holder of this lock then {@link
568: * IllegalMonitorStateException} is thrown.
569: * @throws IllegalMonitorStateException if the current thread does not
570: * hold this lock.
571: */
572: public void unlock() {
573: impl.unlock();
574: }
575:
576: /**
577: * Returns a {@link Condition} instance for use with this
578: * {@link Lock} instance.
579: *
580: * <p>The returned {@link Condition} instance supports the same
581: * usages as do the {@link Object} monitor methods ({@link
582: * Object#wait() wait}, {@link Object#notify notify}, and {@link
583: * Object#notifyAll notifyAll}) when used with the built-in
584: * monitor lock.
585: *
586: * <ul>
587: *
588: * <li>If this lock is not held when any of the {@link Condition}
589: * {@link Condition#await() waiting} or {@link Condition#signal
590: * signalling} methods are called, then an {@link
591: * IllegalMonitorStateException} is thrown.
592: *
593: * <li>When the condition {@link Condition#await() waiting}
594: * methods are called the lock is released and, before they
595: * return, the lock is reacquired and the lock hold count restored
596: * to what it was when the method was called.
597: *
598: * <li>If a thread is {@link Thread#interrupt interrupted} while
599: * waiting then the wait will terminate, an {@link
600: * InterruptedException} will be thrown, and the thread's
601: * interrupted status will be cleared.
602: *
603: * <li> Waiting threads are signalled in FIFO order
604: *
605: * <li>The ordering of lock reacquisition for threads returning
606: * from waiting methods is the same as for threads initially
607: * acquiring the lock, which is in the default case not specified,
608: * but for <em>fair</em> locks favors those threads that have been
609: * waiting the longest.
610: *
611: * </ul>
612: *
613: * @return the Condition object
614: */
615: public Condition newCondition() {
616: return new CondVar(this );
617: }
618:
619: /**
620: * Queries the number of holds on this lock by the current thread.
621: *
622: * <p>A thread has a hold on a lock for each lock action that is not
623: * matched by an unlock action.
624: *
625: * <p>The hold count information is typically only used for testing and
626: * debugging purposes. For example, if a certain section of code should
627: * not be entered with the lock already held then we can assert that
628: * fact:
629: *
630: * <pre>
631: * class X {
632: * ReentrantLock lock = new ReentrantLock();
633: * // ...
634: * public void m() {
635: * assert lock.getHoldCount() == 0;
636: * lock.lock();
637: * try {
638: * // ... method body
639: * } finally {
640: * lock.unlock();
641: * }
642: * }
643: * }
644: * </pre>
645: *
646: * @return the number of holds on this lock by the current thread,
647: * or zero if this lock is not held by the current thread.
648: */
649: public int getHoldCount() {
650: return impl.getHoldCount();
651: }
652:
653: /**
654: * Queries if this lock is held by the current thread.
655: *
656: * <p>Analogous to the {@link Thread#holdsLock} method for built-in
657: * monitor locks, this method is typically used for debugging and
658: * testing. For example, a method that should only be called while
659: * a lock is held can assert that this is the case:
660: *
661: * <pre>
662: * class X {
663: * ReentrantLock lock = new ReentrantLock();
664: * // ...
665: *
666: * public void m() {
667: * assert lock.isHeldByCurrentThread();
668: * // ... method body
669: * }
670: * }
671: * </pre>
672: *
673: * <p>It can also be used to ensure that a reentrant lock is used
674: * in a non-reentrant manner, for example:
675: *
676: * <pre>
677: * class X {
678: * ReentrantLock lock = new ReentrantLock();
679: * // ...
680: *
681: * public void m() {
682: * assert !lock.isHeldByCurrentThread();
683: * lock.lock();
684: * try {
685: * // ... method body
686: * } finally {
687: * lock.unlock();
688: * }
689: * }
690: * }
691: * </pre>
692: * @return <tt>true</tt> if current thread holds this lock and
693: * <tt>false</tt> otherwise.
694: */
695: public boolean isHeldByCurrentThread() {
696: return impl.isHeldByCurrentThread();
697: }
698:
699: /**
700: * Queries if this lock is held by any thread. This method is
701: * designed for use in monitoring of the system state,
702: * not for synchronization control.
703: * @return <tt>true</tt> if any thread holds this lock and
704: * <tt>false</tt> otherwise.
705: */
706: public boolean isLocked() {
707: return impl.isLocked();
708: }
709:
710: /**
711: * Returns true if this lock has fairness set true.
712: * @return true if this lock has fairness set true.
713: */
714: public final boolean isFair() {
715: return impl.isFair();
716: }
717:
718: /**
719: * Returns the thread that currently owns this lock, or
720: * <tt>null</tt> if not owned. Note that the owner may be
721: * momentarily <tt>null</tt> even if there are threads trying to
722: * acquire the lock but have not yet done so. This method is
723: * designed to facilitate construction of subclasses that provide
724: * more extensive lock monitoring facilities.
725: * @return the owner, or <tt>null</tt> if not owned.
726: */
727: protected Thread getOwner() {
728: return impl.getOwner();
729: }
730:
731: /**
732: * Queries whether any threads are waiting to acquire this lock. Note that
733: * because cancellations may occur at any time, a <tt>true</tt>
734: * return does not guarantee that any other thread will ever
735: * acquire this lock. This method is designed primarily for use in
736: * monitoring of the system state.
737: *
738: * @return true if there may be other threads waiting to acquire
739: * the lock.
740: */
741: public final boolean hasQueuedThreads() {
742: return impl.hasQueuedThreads();
743: }
744:
745: /**
746: * Queries whether the given thread is waiting to acquire this
747: * lock. Note that because cancellations may occur at any time, a
748: * <tt>true</tt> return does not guarantee that this thread
749: * will ever acquire this lock. This method is designed primarily for use
750: * in monitoring of the system state.
751: *
752: * @param thread the thread
753: * @return true if the given thread is queued waiting for this lock.
754: * @throws NullPointerException if thread is null
755: */
756: public final boolean hasQueuedThread(Thread thread) {
757: return impl.isQueued(thread);
758: }
759:
760: /**
761: * Returns an estimate of the number of threads waiting to
762: * acquire this lock. The value is only an estimate because the number of
763: * threads may change dynamically while this method traverses
764: * internal data structures. This method is designed for use in
765: * monitoring of the system state, not for synchronization
766: * control.
767: * @return the estimated number of threads waiting for this lock
768: */
769: public final int getQueueLength() {
770: return impl.getQueueLength();
771: }
772:
773: /**
774: * Returns a collection containing threads that may be waiting to
775: * acquire this lock. Because the actual set of threads may change
776: * dynamically while constructing this result, the returned
777: * collection is only a best-effort estimate. The elements of the
778: * returned collection are in no particular order. This method is
779: * designed to facilitate construction of subclasses that provide
780: * more extensive monitoring facilities.
781: * @return the collection of threads
782: */
783: protected Collection getQueuedThreads() {
784: return impl.getQueuedThreads();
785: }
786:
787: // /**
788: // * Queries whether any threads are waiting on the given condition
789: // * associated with this lock. Note that because timeouts and
790: // * interrupts may occur at any time, a <tt>true</tt> return does
791: // * not guarantee that a future <tt>signal</tt> will awaken any
792: // * threads. This method is designed primarily for use in
793: // * monitoring of the system state.
794: // * @param condition the condition
795: // * @return <tt>true</tt> if there are any waiting threads.
796: // * @throws IllegalMonitorStateException if this lock
797: // * is not held
798: // * @throws IllegalArgumentException if the given condition is
799: // * not associated with this lock
800: // * @throws NullPointerException if condition null
801: // */
802: // public boolean hasWaiters(Condition condition) {
803: // if (condition == null)
804: // throw new NullPointerException();
805: // if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
806: // throw new IllegalArgumentException("not owner");
807: // return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
808: // }
809:
810: // /**
811: // * Returns an estimate of the number of threads waiting on the
812: // * given condition associated with this lock. Note that because
813: // * timeouts and interrupts may occur at any time, the estimate
814: // * serves only as an upper bound on the actual number of waiters.
815: // * This method is designed for use in monitoring of the system
816: // * state, not for synchronization control.
817: // * @param condition the condition
818: // * @return the estimated number of waiting threads.
819: // * @throws IllegalMonitorStateException if this lock
820: // * is not held
821: // * @throws IllegalArgumentException if the given condition is
822: // * not associated with this lock
823: // * @throws NullPointerException if condition null
824: // */
825: // public int getWaitQueueLength(Condition condition) {
826: // if (condition == null)
827: // throw new NullPointerException();
828: // if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
829: // throw new IllegalArgumentException("not owner");
830: // return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
831: // }
832:
833: // /**
834: // * Returns a collection containing those threads that may be
835: // * waiting on the given condition associated with this lock.
836: // * Because the actual set of threads may change dynamically while
837: // * constructing this result, the returned collection is only a
838: // * best-effort estimate. The elements of the returned collection
839: // * are in no particular order. This method is designed to
840: // * facilitate construction of subclasses that provide more
841: // * extensive condition monitoring facilities.
842: // * @param condition the condition
843: // * @return the collection of threads
844: // * @throws IllegalMonitorStateException if this lock
845: // * is not held
846: // * @throws IllegalArgumentException if the given condition is
847: // * not associated with this lock
848: // * @throws NullPointerException if condition null
849: // */
850: // protected Collection getWaitingThreads(Condition condition) {
851: // if (condition == null)
852: // throw new NullPointerException();
853: // if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
854: // throw new IllegalArgumentException("not owner");
855: // return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
856: // }
857:
858: /**
859: * Returns a string identifying this lock, as well as its lock
860: * state. The state, in brackets, includes either the String
861: * "Unlocked" or the String "Locked by"
862: * followed by the {@link Thread#getName} of the owning thread.
863: * @return a string identifying this lock, as well as its lock state.
864: */
865: public String toString() {
866: Thread owner = getOwner();
867: return super .toString()
868: + ((owner == null) ? "[Unlocked]"
869: : "[Locked by thread " + owner.getName() + "]");
870: }
871: }
|