ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ReentrantLock.java
Revision: 1.20
Committed: Tue Jul 8 00:46:34 2003 UTC (20 years, 10 months ago) by dl
Branch: MAIN
CVS Tags: HEAD
Changes since 1.19: +1 -1 lines
State: FILE REMOVED
Log Message:
Locks in subpackage; fairness params added

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain. Use, modify, and
4 * redistribute this code in any way without acknowledgement.
5 */
6
7 package java.util.concurrent;
8 import java.util.concurrent.atomic.*;
9 import java.util.Date;
10
11
12 /**
13 * A reentrant mutual exclusion {@link Lock} with the same basic
14 * behavior and semantics as the implicit monitor lock accessed by the
15 * use of <tt>synchronized</tt> methods and statements, but without
16 * the forced block-structured locking and unlocking that occurs with
17 * <tt>synchronized</tt> methods and statements.
18 *
19 * <p>The order in which blocked threads are granted the lock is not
20 * specified.
21 *
22 * <p>If you want a non-reentrant mutual exclusion lock then it is a simple
23 * matter to use a reentrant lock in a non-reentrant way by ensuring that
24 * the lock is not held by the current thread prior to locking.
25 * See {@link #getHoldCount} for a way to check this.
26 *
27 *
28 * <p><tt>ReentrantLock</tt> instances are intended to be used primarily
29 * in before/after constructions such as:
30 *
31 * <pre>
32 * class X {
33 * ReentrantLock lock;
34 * // ...
35 *
36 * public void m() {
37 * lock.lock(); // block until condition holds
38 * try {
39 * // ... method body
40 * } finally {
41 * lock.unlock()
42 * }
43 * }
44 * }
45 * </pre>
46 *
47 * <p>Except where noted, passing a <tt>null</tt> value for any parameter
48 * will result in a {@link NullPointerException} being thrown.
49 *
50 * <h3>Implementation Notes</h3>
51 * <p>This implementation supports the interruption of lock acquisition and
52 * provides a
53 * {@link #newCondition Condition} implementation that supports the
54 * interruption of thread suspension.
55 * It also favors interruption over normal method return.
56 *
57 *
58 * @since 1.5
59 * @spec JSR-166
60 * @revised $Date: 2003/07/01 16:29:52 $
61 * @editor $Author: dl $
62 * @author Doug Lea
63 *
64 **/
65 public class ReentrantLock extends ReentrantLockQueueNode
66 implements Lock, java.io.Serializable {
67 /*
68 The basic fastpath/slowpath algorithm looks like this, ignoring
69 reentrance, cancellation, timeouts, error checking etc:
70 Lock:
71 if (!fair && casOwner(null, currentThread)) // fastpath
72 return;
73 node = create and enq a wait node;
74 for (;;) {
75 if (node is first on queue) {
76 if (casOwner(null, currentThread)) {
77 deq(node);
78 return;
79 }
80 }
81 park(currentThread);
82 }
83
84 Unlock:
85 owner = null; // volatile assignment
86 h = first node on queue;
87 if (h != null) unpark(h's successor's thread);
88
89 * The fast path uses one atomic CAS operation, plus one
90 StoreLoad barrier (i.e., volatile-write-barrier) per
91 lock/unlock pair. The "owner" field is handled as a simple
92 spinlock. To lock, the owner field is set to current thread
93 using conditional atomic update. To unlock, the owner field
94 is set to null, checking if anyone needs waking up, if so
95 doing so. Recursive locks/unlocks instead increment/decrement
96 recursion field.
97
98 * By default, contended locks use a kind of "greedy" /
99 "renouncement" / barging / convoy-avoidance strategy: When a
100 lock is released, a waiting thread is signalled so that it can
101 (re)contend for the lock. It might lose and thus need to
102 rewait. This strategy has much higher throughput than
103 "directed handoff" because it reduces blocking of running
104 threads, but poorer fairness. The wait queue is FIFO, but
105 newly entering threads can barge ahead and grab lock before
106 woken waiters, so acquires are not strictly FIFO, and transfer
107 is not deterministically fair. It is probablistically fair
108 though. Earlier queued threads are allowed to recontend before
109 later queued threads, and each recontention has an unbiased
110 chance to succeed.
111
112 * The base class also sets up support for FairReentrantLock
113 subclass, that differs only in that barging is disabled when
114 there is contention, so locks proceed FIFO. There can be
115 some races in detecting contention, but it is still FIFO from
116 a definable (although complicated to describe) single point,
117 so qualifies as a FIFO lock.
118
119 * The wait queue is a variant of a "CLH" (Craig, Landin, and
120 Hagersten) lock. CLH locks are normally used for spinlocks.
121 We instead use them for blocking locks, but use the same basic
122 tactic of holding the information about whether a thread is
123 released (i.e, eligible to contend for ownership lock) in the
124 predecessor of each node. A node waits until its predecessor
125 says it is released. It is signalled when its predecessor
126 releases the lock. Each node of the queue otherwise serves as
127 a specific-notification-style monitor holding a single waiting
128 thread.
129
130 To enqueue into a CLH lock, you atomically splice it in as new
131 tail. To dequeue, you just set the head field.
132
133 +------+ prev +-----+ +-----+
134 head | | <---- | | <---- | | tail
135 +------+ +-----+ +-----+
136
137 The great thing about CLH Locks is that insertion into a CLH
138 queue requires only a single atomic operation on "tail", so
139 there is a simple atomic point of demarcation from unqueued to
140 queued. Similarly, dequeing involves only updating the
141 "head". However, it takes a bit more work for nodes to
142 determine who their successors are, in part to deal with
143 possible cancellation due to timeouts and interrupts.
144
145 The "prev" links (not used in original CLH locks), are mainly
146 needed to handle cancellation. If a node is cancelled, its
147 successor must be relinked to a non-cancelled predecessor. For
148 explanation in the case of spin locks, see the papers by Scott
149 & Scherer at
150 http://www.cs.rochester.edu/u/scott/synchronization/
151
152 Being first in the queue does not mean that you have the lock,
153 only that you may contend for it (by CAS'ing owner field). So
154 the currently released contender thread may need to rewait.
155
156 We also use "next" links to implement blocking mechanics. The
157 thread id for each node is kept in its node, so a predecessor
158 signals the next node to wake up by traversing next link to
159 determine which thread it is. Determination of successor must
160 avoid races with newly queued nodes to set the "next" fields
161 of their predecessors. This is solved by checking backwards
162 from the atomically updated "tail" when a node's successor
163 appears to be null.
164
165 Cancellation introduces some conservatism to the basic
166 algorithms. Since we must poll for cancellation of other
167 nodes, we can miss noticing whether a cancelled node is ahead
168 or behind us. This is dealt with by always unparking
169 successors upon cancellation, and not letting them park again
170 (by saturating release counts) until they stabilize on a new
171 predecessor.
172
173 * Threads waiting on Conditions use the same kind of nodes, but
174 only need to link them in simple (non-concurrent) linked
175 queues because they are only accessed when lock is held. To
176 wait, a thread makes a node inserted into a condition queue.
177 Upon signal, the node is transferred to the lock queue.
178 Special values of releaseStatus fields are used to mark which
179 queue a node is on.
180
181 * All suspension and resumption of threads uses the internal
182 JSR166 native park/unpark API. These are safe versions of
183 suspend/resume (plus timeout support) that avoid the intrinsic
184 race problems with suspend/resume: Park suspends if not
185 preceded by an unpark. Unpark resumes if waiting, else causes
186 next park not to suspend. While safe and efficient, these are
187 not general-purpose public operations because we cannot allow
188 code outside this package to randomly call these methods --
189 parks and unparks should be matched up. (It is OK to have more
190 unparks than unparks, but it causes threads to spuriously wake
191 up. So minimizing excessive unparks is a performance concern.)
192
193 * The ReentrantLock class extends package-private
194 ReentrantLockQueueNode class as an expedient and efficient
195 (although slightly sleazy) solution to serialization and
196 initialization problems -- we need head and tail nodes to be
197 initialized to an otherwise useless dummy node, so use the
198 ReeantrantLock itself as that node.
199 */
200
201 /*
202 Note that all fields are transient and defined in a way that
203 deserialized locks are in initial unlocked state.
204 */
205
206 /**
207 * Creates an instance of <tt>ReentrantLock</tt>.
208 */
209 public ReentrantLock() { }
210
211 /**
212 * Current owner of lock, or null iff the lock is free. Acquired
213 * only using CAS.
214 */
215 private transient volatile Thread owner;
216
217 /** Number of recursive acquires. Note: total holds = recursions+1 */
218 private transient int recursions;
219
220 /** Head of the wait queue, initialized to point to self as dummy node */
221 private transient volatile ReentrantLockQueueNode head = this;
222
223 /** Tail of the wait queue, initialized to point to self as dummy node */
224 private transient volatile ReentrantLockQueueNode tail = this;
225
226 // Atomics support
227
228 private final static AtomicReferenceFieldUpdater ownerUpdater = new AtomicReferenceFieldUpdater (new ReentrantLock[0], new Thread[0], "owner");
229 private final static AtomicReferenceFieldUpdater tailUpdater = new AtomicReferenceFieldUpdater (new ReentrantLock[0], new ReentrantLockQueueNode[0], "tail");
230 private final static AtomicReferenceFieldUpdater headUpdater = new AtomicReferenceFieldUpdater (new ReentrantLock[0], new ReentrantLockQueueNode[0], "head");
231 private final static AtomicIntegerFieldUpdater releaseStatusUpdater =
232 new AtomicIntegerFieldUpdater (new ReentrantLockQueueNode[0], "releaseStatus");
233
234 private boolean acquireOwner(Thread current) {
235 return ownerUpdater.compareAndSet(this, null, current);
236 }
237
238 private boolean casTail(ReentrantLockQueueNode cmp, ReentrantLockQueueNode val) {
239 return tailUpdater.compareAndSet(this, cmp, val);
240 }
241
242 private boolean casHead(ReentrantLockQueueNode cmp, ReentrantLockQueueNode val) {
243 return headUpdater.compareAndSet(this, cmp, val);
244 }
245
246 // casReleaseStatus non-private because also accessed by Conditions
247 final boolean casReleaseStatus(ReentrantLockQueueNode node, int cmp, int val) {
248 return releaseStatusUpdater.compareAndSet(node, cmp, val);
249 }
250
251 /**
252 * Special value for releaseStatus indicating that node is cancelled.
253 * Must be a large positive number.
254 */
255 private static final int CANCELLED = Integer.MAX_VALUE;
256
257 /**
258 * Special value for node releaseStatus indicating that node is on a
259 * condition queue. Must be large negative number.
260 */
261 private static final int ON_CONDITION_QUEUE = Integer.MIN_VALUE;
262
263 /**
264 * Special value for node releaseStatus indicating that node is in
265 * process of transfer. Must be negative and greater than
266 * ON_CONDITION_QUEUE.
267 */
268 private static final int TRANSFERRING = ON_CONDITION_QUEUE + 1;
269
270 /**
271 * Return whether lock wait queue is empty
272 * @return true if no threads are waiting for lock
273 */
274 final boolean queueEmpty() {
275 ReentrantLockQueueNode h = head; // force order of the volatile reads
276 return h == tail;
277 }
278
279 /**
280 * Insert node into queue. Return predecessor.
281 * @param node the node to insert
282 * @return node's predecessor
283 */
284 private ReentrantLockQueueNode enq(ReentrantLockQueueNode node) {
285 for (;;) {
286 ReentrantLockQueueNode p = tail;
287 node.prev = p; // prev must be valid before/upon CAS
288 if (casTail(p, node)) {
289 p.next = node; // Note: next field assignment lags CAS
290 return p;
291 }
292 }
293 }
294
295 /**
296 * Return true if it is OK to take fast path to lock.
297 * Overridden in FairReentrantLock.
298 * @return true (for non-fair locks)
299 */
300 boolean canBarge() {
301 return true;
302 }
303
304 /**
305 * Main locking code, parameterized across different policies.
306 * @param current current thread
307 * @param node its wait-node, if it already exists; else null in
308 * which case it is created,
309 * @param interruptible - true if can abort for interrupt or timeout
310 * @param nanos time to wait, or zero if untimed
311 * @return true if lock acquired (can be false only if interruptible)
312 */
313 final boolean doLock(Thread current,
314 ReentrantLockQueueNode node,
315 boolean interruptible,
316 long nanos) {
317 /*
318 * Bypass queueing if a recursive lock
319 */
320 if (owner == current) {
321 ++recursions;
322 return true;
323 }
324
325 long lastTime = 0; // for adjusting timeouts, below
326 boolean interrupted = false; // for restoring interrupt status on exit
327
328 /*
329 * p is our predecessor node, that holds releaseStatus giving
330 * permission to try to obtain lock if we are first in queue.
331 */
332 ReentrantLockQueueNode p;
333
334 /*
335 * Create and enqueue node if not already created. Nodes
336 * transferred from condition queues will already be created
337 * and queued.
338 */
339 if (node == null) {
340 node = new ReentrantLockQueueNode(current);
341 p = enq(node);
342 }
343 else
344 p = node.prev;
345
346 /*
347 * Repeatedly try to get ownership if first in queue, else
348 * block.
349 */
350 for (;;) {
351 /*
352 * If we are the first thread in queue, try to get the
353 * lock. (We must not try to get lock if we are not
354 * first.) Note that if we become first after p == head
355 * check, all is well -- we can be sure an unlocking
356 * thread will signal us.
357 */
358
359 if (p == head && acquireOwner(current)) {
360 if (interrupted) // re-interrupt on exit
361 current.interrupt();
362
363 p.next = null; // clear for GC and to suppress signals
364 node.thread = null;
365 node.prev = null;
366 head = node;
367 return true;
368 }
369
370 int releaseStatus = p.releaseStatus;
371
372 /*
373 * If our predecessor was cancelled, use its predecessor.
374 * There will always be a non-cancelled one somewhere
375 * because head node is never cancelled, so at worst we
376 * will hit it. (Note that because head is never
377 * cancelled, we can perform this check after trying to
378 * acquire ownership).
379 */
380 if (releaseStatus == CANCELLED) {
381 node.prev = p = p.prev;
382 }
383
384 /*
385 * Retry if already released.
386 */
387 else if (releaseStatus > 0) {
388 casReleaseStatus(p, releaseStatus, 0);
389 }
390
391 /*
392 * Wait if we are not not first in queue, or if we are
393 * first, we have tried to acquire owner and failed since
394 * either entry or last release. (Note that releaseStatus can
395 * already be less than zero if we spuriously returned
396 * from a previous park or got new a predecessor due to
397 * cancellation.)
398 *
399 * We also don't wait if atomic decrement of releaseStatus
400 * fails. We just continue main loop on failure to
401 * atomically update releaseStatus because interference
402 * causing failure is almost surely due to someone
403 * releasing us anyway.
404 *
405 * Each wait consumes all available releases. Normally
406 * there is only one anyway because release doesn't bother
407 * incrementing if already positive.
408 *
409 */
410 else if (casReleaseStatus(p, releaseStatus, -1)) {
411 // Update and check timeout value
412 if (nanos > 0) {
413 long now = TimeUnit.nanoTime();
414 if (lastTime != 0) {
415 nanos -= now - lastTime;
416 if (nanos == 0) // avoid zero
417 nanos = -1;
418 }
419 lastTime = now;
420 }
421
422 if (nanos >= 0)
423 JSR166Support.park(node, false, nanos);
424
425 if (!interruptible) {
426 if (Thread.interrupted()) // consume interrupt for now
427 interrupted = true;
428 }
429 else if (nanos < 0 || current.isInterrupted()) {
430 node.thread = null; // disable signals
431 // don't need CAS here:
432 releaseStatusUpdater.set(node, CANCELLED);
433 signalSuccessor(node);
434 return false;
435 }
436 }
437 }
438 }
439
440 /**
441 * Wake up node's successor, if one exists
442 * @param node the current node
443 */
444 private void signalSuccessor(ReentrantLockQueueNode node) {
445 /*
446 * Find successor -- normally just node.next.
447 */
448 ReentrantLockQueueNode s = node.next;
449
450 /*
451 * if s is cancelled, traverse through next's.
452 */
453
454 while (s != null && s.releaseStatus == CANCELLED) {
455 node = s;
456 s = s.next;
457 }
458
459 /*
460 * If successor appears to be null, check to see if a newly
461 * queued node is successor by starting at tail and working
462 * backwards. We don't expect this loop to trigger often,
463 * and hardly ever to iterate.
464 */
465
466 if (s == null) {
467 ReentrantLockQueueNode t = tail;
468 for (;;) {
469 /*
470 * If t == node, there is no successor. And t's
471 * predecessor is null if we are lagging so far behind
472 * the actions of other nodes/threads that an
473 * intervening head.prev was nulled by some
474 * non-cancelled successor of node. In which case,
475 * there's no live successor.
476 */
477 if (t == node || t == null)
478 return;
479 ReentrantLockQueueNode tp = t.prev;
480 if (tp == node) {
481 s = t;
482 break;
483 }
484 t = tp;
485
486 /*
487 * Before iterating, check to see if link has
488 * appeared.
489 */
490 ReentrantLockQueueNode n = node.next;
491 if (n != null) {
492 s = n;
493 break;
494 }
495 }
496 }
497
498 Thread thr = s.thread;
499 // Don't bother signalling if has lock
500 if (thr != null && thr != owner)
501 JSR166Support.unpark(s, thr);
502 }
503
504
505 /**
506 * Increment releaseStatus and signal next thread in queue if one
507 * exists and is waiting. Called only by unlock. This code is split
508 * out from unlock to encourage inlining of non-contended cases.
509 */
510 private void releaseFirst() {
511 for (;;) {
512 ReentrantLockQueueNode h = head;
513 if (h == tail) // No successor
514 return;
515 /*
516 if (owner != null) // Don't bother if some thread got lock
517 return;
518 */
519 int c = h.releaseStatus;
520 if (c > 0) // Don't need signal if already positive
521 return;
522 if (casReleaseStatus(h, c, (c < 0) ? 0 : 1)) { // saturate at 1
523 if (c < 0)
524 signalSuccessor(h);
525 return;
526 }
527 // else retry if CAS fails
528 }
529 }
530
531 /**
532 * Attempts to release this lock.
533 * <p>If the current thread is the
534 * holder of this lock then the hold count is decremented. If the
535 * hold count is now zero then the lock is released. If the
536 * current thread is not the holder of this lock then {@link
537 * IllegalMonitorStateException} is thrown.
538 * @throws IllegalMonitorStateException if the current thread does not
539 * hold this lock.
540 */
541 public void unlock() {
542 if (Thread.currentThread() != owner)
543 throw new IllegalMonitorStateException();
544
545 if (recursions > 0) {
546 --recursions;
547 return;
548 }
549
550 ownerUpdater.set(this, null);
551 for (;;) {
552 ReentrantLockQueueNode h = head;
553 if (h == tail) // No successor
554 return;
555 int c = h.releaseStatus;
556 if (c > 0) // Don't need signal if already positive
557 return;
558 if (casReleaseStatus(h, c, (c < 0) ? 0 : 1)) { // saturate at 1
559 signalSuccessor(h);
560 return;
561 }
562 // else retry if CAS fails
563 }
564 }
565
566 /**
567 * Acquire the lock.
568 * <p>Acquires the lock if it is not held by another thread and returns
569 * immediately, setting the lock hold count to one.
570 * <p>If the current thread
571 * already holds the lock then the hold count is incremented by one and
572 * the method returns immediately.
573 * <p>If the lock is held by another thread then the
574 * current thread becomes disabled for thread scheduling
575 * purposes and lies dormant until the lock has been acquired,
576 * at which time the lock hold count is set to one.
577 */
578 public void lock() {
579 Thread current = Thread.currentThread();
580 if (!canBarge() || !acquireOwner(current))
581 doLock(current, null, false, 0);
582
583 }
584
585 /**
586 * Acquires the lock unless the current thread is
587 * {@link Thread#interrupt interrupted}.
588 * <p>Acquires the lock if it is not held by another thread and returns
589 * immediately, setting the lock hold count to one.
590 * <p>If the current thread already holds this lock then the hold count
591 * is incremented by one and the method returns immediately.
592 * <p>If the lock is held by another thread then the
593 * current thread becomes disabled for thread scheduling
594 * purposes and lies dormant until one of two things happens:
595 * <ul>
596 * <li> The lock is acquired by the current thread; or
597 * <li> Some other thread {@link Thread#interrupt interrupts} the current
598 * thread.
599 * </ul>
600 * <p>If the lock is acquired by the current thread then the lock hold
601 * count is set to one.
602 * <p>If the current thread:
603 * <ul>
604 * <li>has its interrupted status set on entry to this method; or
605 * <li>is {@link Thread#interrupt interrupted} while acquiring
606 * the lock,
607 * </ul>
608 * then {@link InterruptedException} is thrown and the current thread's
609 * interrupted status is cleared.
610 * <p>In this implementation, as this method is an explicit interruption
611 * point, preference is
612 * given to responding to the interrupt over normal or reentrant
613 * acquisition of the lock.
614 *
615 * @throws InterruptedException if the current thread is interrupted
616 */
617 public void lockInterruptibly() throws InterruptedException {
618 Thread current = Thread.currentThread();
619 if (!Thread.interrupted()) {
620 if ((canBarge() && acquireOwner(current)) ||
621 doLock(current, null, true, 0))
622 return;
623 Thread.interrupted(); // clear interrupt status on failure
624 }
625 throw new InterruptedException();
626 }
627
628 /**
629 * Acquires the lock only if it is not held by another thread at the time
630 * of invocation.
631 * <p>Acquires the lock if it is not held by another thread and returns
632 * immediately with the value <tt>true</tt>, setting the lock hold count
633 * to one.
634 * <p> If the current thread
635 * already holds this lock then the hold count is incremented by one and
636 * the method returns <tt>true</tt>.
637 * <p>If the lock is held by another thread then this method will return
638 * immediately with the value <tt>false</tt>.
639 *
640 * @return <tt>true</tt>if the lock was free and was acquired by the
641 * current thread, or the lock was already held by the current thread; and
642 * <tt>false</tt> otherwise.
643 */
644 public boolean tryLock() {
645 Thread current = Thread.currentThread();
646 if (acquireOwner(current))
647 return true;
648 if (owner == current) {
649 ++recursions;
650 return true;
651 }
652 return false;
653 }
654
655 /**
656 *
657 * Acquires the lock if it is not held by another thread within the given
658 * waiting time and the current thread has not been
659 * {@link Thread#interrupt interrupted}.
660 * <p>Acquires the lock if it is not held by another thread and returns
661 * immediately with the value <tt>true</tt>, setting the lock hold count
662 * to one.
663 * <p> If the current thread
664 * already holds this lock then the hold count is incremented by one and
665 * the method returns <tt>true</tt>.
666 * <p>If the lock is held by another thread then the
667 * current thread becomes disabled for thread scheduling
668 * purposes and lies dormant until one of three things happens:
669 * <ul>
670 * <li> The lock is acquired by the current thread; or
671 * <li> Some other thread {@link Thread#interrupt interrupts} the current
672 * thread; or
673 * <li> The specified waiting time elapses
674 * </ul>
675 * <p>If the lock is acquired then the value <tt>true</tt> is returned and
676 * the lock hold count is set to one.
677 * <p>If the current thread:
678 * <ul>
679 * <li>has its interrupted status set on entry to this method; or
680 * <li>is {@link Thread#interrupt interrupted} while acquiring
681 * the lock,
682 * </ul>
683 * then {@link InterruptedException} is thrown and the current thread's
684 * interrupted status is cleared.
685 * <p>If the specified waiting time elapses then the value <tt>false</tt>
686 * is returned.
687 * The given waiting time is a best-effort lower bound. If the time is
688 * less than or equal to zero, the method will not wait at all.
689 * <p>In this implementation, as this method is an explicit interruption
690 * point, preference is
691 * given to responding to the interrupt over normal or reentrant
692 * acquisition of the lock, and over reporting the elapse of the waiting
693 * time.
694 *
695 *
696 * @param timeout the time to wait for the lock
697 * @param unit the time unit of the timeout argument
698 *
699 * @return <tt>true</tt> if the lock was free and was acquired by the
700 * current thread, or the lock was already held by the current thread; and
701 * <tt>false</tt> if the waiting time elapsed before the lock could be
702 * acquired.
703 *
704 * @throws InterruptedException if the current thread is interrupted
705 *
706 */
707 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
708 if (unit == null)
709 throw new NullPointerException();
710 if (Thread.interrupted())
711 throw new InterruptedException();
712 Thread current = Thread.currentThread();
713 if (canBarge() && acquireOwner(current))
714 return true;
715 if (owner == current) { // check recursions before timeout
716 ++recursions;
717 return true;
718 }
719 if (timeout <= 0)
720 return false;
721 if (doLock(current, null, true, unit.toNanos(timeout)))
722 return true;
723 if (Thread.interrupted())
724 throw new InterruptedException();
725 return false; // timed out
726 }
727
728
729 /**
730 * Queries the number of holds on this lock by the current thread.
731 * <p>A thread has a hold on a lock for each lock action that is not
732 * matched by an unlock action.
733 * <p>The hold count information is typically only used for testing and
734 * debugging purposes. For example, if a certain section of code should
735 * not be entered with the lock already held then we can assert that
736 * fact:
737 * <pre>
738 * class X {
739 * ReentrantLock lock = new ReentrantLock();
740 * // ...
741 *
742 * public void m() {
743 * assert lock.getHoldCount() == 0;
744 * lock.lock();
745 * try {
746 * // ... method body
747 * } finally {
748 * lock.unlock()
749 * }
750 * }
751 * }
752 * </pre>
753 *
754 * @return the number of holds on this lock by the current thread,
755 * or zero if this lock is not held by the current thread.
756 **/
757 public int getHoldCount() {
758 return (owner == Thread.currentThread()) ? recursions + 1 : 0;
759 }
760
761 /**
762 * Queries if this lock is held by the current thread.
763 * <p>Analogous to the {@link Thread#holdsLock} method for built-in
764 * monitor locks, this method is typically used for debugging and
765 * testing. For example, a method that should only be called while
766 * a lock is held can assert that this is the case:
767 * <pre>
768 * class X {
769 * ReentrantLock lock = new ReentrantLock();
770 * // ...
771 *
772 * public void m() {
773 * assert lock.isHeldByCurrentThread();
774 * // ... method body
775 * }
776 * }
777 * </pre>
778 *
779 * @return <tt>true</tt> if current thread holds this lock and
780 * <tt>false</tt> otherwise.
781 **/
782 public boolean isHeldByCurrentThread() {
783 return (owner == Thread.currentThread());
784 }
785
786
787 /**
788 * Queries if this lock is held by any thread. This method is
789 * designed for use in monitoring, not for synchronization control.
790 * @return <tt>true</tt> if any thread holds this lock and
791 * <tt>false</tt> otherwise.
792 **/
793 public boolean isLocked() {
794 return owner != null;
795 }
796
797 /**
798 * Reconstitute by resetting head and tail to point back to the lock.
799 * @param s the stream
800 */
801 private void readObject(java.io.ObjectInputStream s)
802 throws java.io.IOException, ClassNotFoundException {
803 s.defaultReadObject();
804 head = tail = this;
805 }
806
807 /**
808 * Returns a {@link Condition} instance for use with this
809 * {@link Lock} instance.
810 *
811 * <p>The returned {@link Condition} instance has the same behavior and
812 * usage
813 * restrictions with this lock as the {@link Object} monitor methods
814 * ({@link Object#wait() wait}, {@link Object#notify notify}, and
815 * {@link Object#notifyAll notifyAll}) have with the built-in monitor
816 * lock:
817 * <ul>
818 * <li>If this lock is not held when any of the {@link Condition}
819 * {@link Condition#await() waiting} or {@link Condition#signal signalling}
820 * methods are called, then an {@link IllegalMonitorStateException} is
821 * thrown.
822 * <li>When the condition {@link Condition#await() waiting} methods are
823 * called the lock is released and before they return the lock is
824 * reacquired and the lock hold count restored to what it was when the
825 * method was called.
826 * <li>If a thread is {@link Thread#interrupt interrupted} while waiting
827 * then the wait will terminate, an {@link InterruptedException} will be
828 * thrown, and the thread's interrupted status will be cleared.
829 * <li>The order in which waiting threads are signalled is not specified.
830 * <li>The order in which threads returning from a wait, and threads trying
831 * to acquire the lock, are granted the lock, is not specified.
832 * </ul>
833 * @return the Condition object
834 */
835 public Condition newCondition() {
836 return new ReentrantLockConditionObject();
837 }
838
839 // Helper methods for Conditions
840
841 /**
842 * Return true if a node, always one that was initially placed on
843 * a condition queue, is off the condition queue (and thus,
844 * normally is now on lock queue.)
845 */
846 boolean isOffConditionQueue(ReentrantLockQueueNode w) {
847 return w.releaseStatus > TRANSFERRING;
848 }
849
850 /**
851 * Transfer a node from a condition queue onto lock queue.
852 * Return true if successful (i.e., node not cancelled)
853 */
854 final boolean transferToLockQueue(ReentrantLockQueueNode node) {
855 /*
856 * Atomically change status to TRANSFERRING to avoid races
857 * with cancelling waiters. We use a special value that causes
858 * any waiters spuriously waking up to re-park until the node
859 * has been placed on lock queue.
860 */
861 if (!casReleaseStatus(node, ON_CONDITION_QUEUE, TRANSFERRING))
862 return false;
863
864 /*
865 * Splice onto queue
866 */
867 ReentrantLockQueueNode p = enq(node);
868
869 /*
870 * Establish normal lock-queue releaseStatus for node. The
871 * CAS can fail if node already was involved in a cancellation
872 * on lock-queue, in which case we signal to be sure.
873 */
874 if (!casReleaseStatus(node, TRANSFERRING, 0))
875 signalSuccessor(node);
876
877 /*
878 * Ensure releaseStatus of predecessor is negative to indicate
879 * that thread is (probably) waiting. If attempt to set releaseStatus
880 * fails or is pred is/becomes cancelled, wake up successor
881 * (which will ordinarily be "node") to resynch.
882 */
883
884 for (;;) {
885 int c = p.releaseStatus;
886 if (c < 0 || (c != CANCELLED && casReleaseStatus(p, c, -1)))
887 break;
888 signalSuccessor(p);
889 if (c == CANCELLED)
890 break;
891 }
892
893 return true;
894 }
895
896 /**
897 * Hook method used by ReentrantReadWriteLock. Called
898 * before unlocking lock to enter wait.
899 */
900 void beforeWait() { }
901
902
903 /**
904 * Hook method used by ReentrantReadWriteLock. Called
905 * after locking lock after exiting wait.
906 */
907 void afterWait() { }
908
909 private class ReentrantLockConditionObject implements Condition, java.io.Serializable {
910 /*
911 * Because condition queues are accessed only when locks are
912 * already held, we just need a simple linked queue to hold
913 * nodes while they are waiting on conditions. They are then
914 * transferred to the lock queue to re-acquire locks.
915 */
916
917 /**
918 * First node of condition queue.
919 */
920 private transient ReentrantLockQueueNode firstWaiter;
921
922 /**
923 * Last node of condition queue.
924 */
925 private transient ReentrantLockQueueNode lastWaiter;
926
927 /**
928 * Basic linked queue insertion.
929 */
930 private ReentrantLockQueueNode addWaiter(Thread current) {
931 ReentrantLockQueueNode w = new ReentrantLockQueueNode(current);
932 w.releaseStatus = ON_CONDITION_QUEUE;
933 if (lastWaiter == null)
934 firstWaiter = lastWaiter = w;
935 else {
936 ReentrantLockQueueNode t = lastWaiter;
937 lastWaiter = w;
938 t.next = w;
939 }
940 return w;
941 }
942
943 /**
944 * Main code for signal. Dequeue and transfer nodes until hit
945 * non-cancelled one or null. Split out from signal to
946 * encourage compilers to inline the case of no waiters.
947 * @param first the first node on condition queue
948 */
949 private void doSignal(ReentrantLockQueueNode first) {
950 do {
951 if ( (firstWaiter = first.next) == null)
952 lastWaiter = null;
953 first.next = null;
954 if (transferToLockQueue(first))
955 return;
956 first = firstWaiter;
957 } while (first != null);
958 }
959
960 public void signal() {
961 if (Thread.currentThread() != owner)
962 throw new IllegalMonitorStateException();
963 ReentrantLockQueueNode w = firstWaiter;
964 if (w != null)
965 doSignal(w);
966 }
967
968 public void signalAll() {
969 if (Thread.currentThread() != owner)
970 throw new IllegalMonitorStateException();
971 // Pull off list all at once and traverse.
972 ReentrantLockQueueNode w = firstWaiter;
973 if (w != null) {
974 lastWaiter = firstWaiter = null;
975 do {
976 ReentrantLockQueueNode n = w.next;
977 w.next = null;
978 transferToLockQueue(w);
979 w = n;
980 } while (w != null);
981 }
982 }
983
984 /*
985 * Various flavors of wait. Each almost the same, but
986 * annoyingly different and no nice way to factor common code.
987 */
988
989 public void await() throws InterruptedException {
990 Thread current = Thread.currentThread();
991 if (current != owner) throw new IllegalMonitorStateException();
992
993 ReentrantLockQueueNode w = addWaiter(current);
994 beforeWait();
995 int recs = recursions;
996 unlock();
997 boolean wasInterrupted = false;
998
999 if (!isOffConditionQueue(w)) {
1000 for (;;) {
1001 JSR166Support.park(w, false, 0);
1002 if (isOffConditionQueue(w))
1003 break;
1004 if ( (wasInterrupted = Thread.interrupted()) ) {
1005 if (casReleaseStatus(w, ON_CONDITION_QUEUE,
1006 CANCELLED)) {
1007 w.thread = null;
1008 w = null;
1009 }
1010 break;
1011 }
1012 }
1013 }
1014
1015 /*
1016 * If we exited above loop due to cancellation, then w is
1017 * null, and doLock will make a new lock node for
1018 * us. Otherwise, upon exit, our node is already in the
1019 * lock queue when doLock is called.
1020 */
1021 doLock(current, w, false, 0);
1022
1023 recursions = recs;
1024 afterWait();
1025
1026 if (wasInterrupted || Thread.interrupted())
1027 throw new InterruptedException();
1028 }
1029
1030 public void awaitUninterruptibly() {
1031 Thread current = Thread.currentThread();
1032 if (current != owner) throw new IllegalMonitorStateException();
1033
1034 ReentrantLockQueueNode w = addWaiter(current);
1035 beforeWait();
1036 int recs = recursions;
1037 unlock();
1038
1039 boolean wasInterrupted = false;
1040 while (!isOffConditionQueue(w)) {
1041 JSR166Support.park(w, false, 0);
1042 if (Thread.interrupted())
1043 wasInterrupted = true;
1044 }
1045
1046 doLock(current, w, false, 0);
1047 recursions = recs;
1048 afterWait();
1049 // avoid re-interrupts on exit
1050 if (wasInterrupted && !current.isInterrupted())
1051 current.interrupt();
1052 }
1053
1054
1055 public long awaitNanos(long nanos) throws InterruptedException {
1056 Thread current = Thread.currentThread();
1057 if (current != owner) throw new IllegalMonitorStateException();
1058
1059 ReentrantLockQueueNode w = addWaiter(current);
1060 beforeWait();
1061 int recs = recursions;
1062 unlock();
1063
1064 if (nanos <= 0) nanos = 1; // park arg must be positive
1065 long timeLeft = nanos;
1066 long startTime = TimeUnit.nanoTime();
1067 boolean wasInterrupted = false;
1068
1069 if (!isOffConditionQueue(w)) {
1070 for (;;) {
1071 JSR166Support.park(w, false, timeLeft);
1072 if (isOffConditionQueue(w))
1073 break;
1074
1075 if ((wasInterrupted = Thread.interrupted()) ||
1076 (timeLeft = nanos - (TimeUnit.nanoTime() - startTime)) <= 0) {
1077 if (casReleaseStatus(w, ON_CONDITION_QUEUE,
1078 CANCELLED)) {
1079 w.thread = null;
1080 w = null;
1081 }
1082 break;
1083 }
1084 }
1085 }
1086
1087 doLock(current, w, false, 0);
1088 recursions = recs;
1089 afterWait();
1090
1091 if (wasInterrupted || Thread.interrupted())
1092 throw new InterruptedException();
1093 else if (timeLeft <= 0)
1094 return timeLeft;
1095 else
1096 return nanos - (TimeUnit.nanoTime() - startTime);
1097 }
1098
1099 public boolean awaitUntil(Date deadline) throws InterruptedException {
1100 Thread current = Thread.currentThread();
1101 if (current != owner) throw new IllegalMonitorStateException();
1102
1103 ReentrantLockQueueNode w = addWaiter(current);
1104 beforeWait();
1105 int recs = recursions;
1106 unlock();
1107
1108 boolean wasInterrupted = false;
1109 boolean cancelled = false;
1110 long abstime = deadline.getTime();
1111
1112 if (!isOffConditionQueue(w)) {
1113 for (;;) {
1114 JSR166Support.park(w, true, abstime);
1115 if (isOffConditionQueue(w))
1116 break;
1117
1118 if ( (wasInterrupted = Thread.interrupted()) ||
1119 System.currentTimeMillis() <= abstime) {
1120 if (casReleaseStatus(w, ON_CONDITION_QUEUE,
1121 CANCELLED)) {
1122 w.thread = null;
1123 w = null;
1124 cancelled = true;
1125 }
1126 break;
1127 }
1128 }
1129 }
1130
1131 doLock(current, w, false, 0);
1132 recursions = recs;
1133 afterWait();
1134
1135 if (wasInterrupted || Thread.interrupted())
1136 throw new InterruptedException();
1137 return !cancelled;
1138 }
1139
1140 public boolean await(long time, TimeUnit unit) throws InterruptedException {
1141 return awaitNanos(unit.toNanos(time)) > 0;
1142 }
1143
1144 }
1145
1146 }
1147
1148 /**
1149 * Node class for threads waiting for locks. This cannot be nested
1150 * inside ReentrantLock because of Java inheritance circularity rules.
1151 */
1152 class ReentrantLockQueueNode {
1153 /**
1154 * Controls whether successor node is allowed to try to obtain
1155 * ownership. Acts as a saturating (in both directions) counting
1156 * semaphore: Upon each wait, the releaseStatus is reduced to zero
1157 * if positive, else reduced to negative, in which case the thread
1158 * will park. The releaseStatus is incremented on each unlock that
1159 * would enable successor thread to obtain lock (succeeding if
1160 * there is no contention). The special value of CANCELLED is used
1161 * to mean that the releaseStatus cannot be either incremented or
1162 * decremented. The special value of ON_CONDITION_QUEUE is used
1163 * when nodes are on conditions queues instead of lock queue, and
1164 * the special value TRANSFERRING is used while signals are in
1165 * progress.
1166 */
1167 transient volatile int releaseStatus;
1168
1169 /**
1170 * Link to predecessor node that current node/thread relies on
1171 * for checking releaseStatus. Assigned once during enqueing,
1172 * and nulled out (for sake of GC) only upon dequeuing. Upon
1173 * cancellation, we do NOT adjust this field, but simply
1174 * traverse through prev's until we hit a non-cancelled node.
1175 * A valid predecessor will always exist because the head node
1176 * is never cancelled.
1177 */
1178 transient volatile ReentrantLockQueueNode prev;
1179
1180 /**
1181 * Link to the successor node that the current node/thread
1182 * unparks upon lock release. Assigned once during enquing.
1183 * Upon cancellation, we do NOT adjust this field, but simply
1184 * traverse through next's until we hit a non-cancelled node,
1185 * (or null if at end of queue). The enqueue operation does
1186 * not assign next field of a predecessor until after
1187 * attachment, so seeing a null next field not necessarily
1188 * mean that node is at end of queue. However, if a next field
1189 * appears to be null, we can scan prev's from the tail to
1190 * double-check.
1191 */
1192 transient volatile ReentrantLockQueueNode next;
1193
1194 /**
1195 * The thread that enqueued this node. Initialized on
1196 * construction and nulled out after use. Note that this need
1197 * not be declared volatile since it is always accessed after
1198 * traversing volatile links, and written before writing
1199 * links.
1200 */
1201 transient Thread thread;
1202
1203 /**
1204 * TEMPORARY field for use only by emulated version of park/unpark.
1205 * Remove when emulation package is phased out.
1206 */
1207 transient int parkSemaphore;
1208
1209 ReentrantLockQueueNode() { }
1210 ReentrantLockQueueNode(Thread t) { thread = t; }
1211 }