ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ReentrantLock.java
Revision: 1.13
Committed: Wed Jun 11 23:06:34 2003 UTC (21 years ago) by dholmes
Branch: MAIN
Changes since 1.12: +21 -17 lines
Log Message:
Updated interrupt semantics

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