ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ReentrantLock.java
Revision: 1.10
Committed: Wed Jun 11 02:09:28 2003 UTC (21 years ago) by dl
Branch: MAIN
Changes since 1.9: +11 -6 lines
Log Message:
Clear interrupt in lockInterruptibly

File Contents

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