ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ReentrantLock.java
Revision: 1.8
Committed: Mon Jun 9 02:32:05 2003 UTC (21 years ago) by dl
Branch: MAIN
Changes since 1.7: +12 -16 lines
Log Message:
New ScheduledExecuor methods; minor javadoc cleanup

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.8 * @revised $Date: 2003/06/07 17:10:36 $
57 dl 1.3 * @editor $Author: dl $
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 dl 1.8 * Attempts to release this lock. If the current thread is the
546 dl 1.2 * holder of this lock then the hold count is decremented. If the
547 dl 1.8 * hold count is now zero then the lock is released. If the
548 dl 1.2 * current thread is not the holder of this lock then {@link
549     * IllegalMonitorStateException} is thrown.
550     * @throws IllegalMonitorStateException if the current thread does not
551     * hold this lock.
552     */
553     public void unlock() {
554     checkOwner(Thread.currentThread());
555 dl 1.6 if (recursions > 0)
556 dl 1.2 --recursions;
557 dl 1.6 else {
558     ownerUpdater.set(this, null);
559     if (tail != this) // don't bother if never contended
560     releaseFirst();
561 dl 1.2 }
562     }
563    
564     /**
565     * Acquire the lock.
566 tim 1.1 * <p>Acquires the lock if it is not held be another thread and returns
567     * immediately, setting the lock hold count to one.
568     * <p>If the current thread
569     * already holds the lock then the hold count is incremented by one and
570     * the method returns immediately.
571     * <p>If the lock is held by another thread then the
572     * the current thread thread becomes disabled for thread scheduling
573     * purposes and lies dormant until the lock has been acquired
574     * at which time the lock hold count is set to one.
575     */
576 dl 1.2 public void lock() {
577     Thread current = Thread.currentThread();
578 dl 1.6 if (!canBarge() || !acquireOwner(current))
579     doLock(current, null, false, 0);
580 dl 1.7
581 dl 1.2 }
582 tim 1.1
583     /**
584     * Acquires the lock unless the current thread is
585     * {@link Thread#interrupt interrupted}.
586     * <p>Acquires the lock if it is not held by another thread and returns
587     * immediately, setting the lock hold count to one.
588     * <p>If the current thread already holds this lock then the hold count
589     * is incremented by one and the method returns immediately.
590     * <p>If the lock is held by another thread then the
591     * the current thread becomes disabled for thread scheduling
592     * purposes and lies dormant until one of two things happens:
593     * <ul>
594     * <li> The lock is acquired by the current thread; or
595     * <li> Some other thread {@link Thread#interrupt interrupts} the current
596     * thread.
597     * </ul>
598     * <p>If the lock is acquired by the current thread then the lock hold
599     * count is set to one.
600     * <p>If the current thread:
601     * <ul>
602     * <li>has its interrupted status set on entry to this method; or
603     * <li>is {@link Thread#interrupt interrupted} while waiting to acquire
604     * the lock,
605     * </ul>
606     * then {@link InterruptedException} is thrown and the current thread's
607     * interrupted status is cleared. As this method is an explicit
608     * interruption point, preference is given to responding to the interrupt
609     * over reentrant acquisition of the lock.
610     *
611     *
612     * @throws InterruptedException if the current thread is interrupted
613     */
614 dl 1.2 public void lockInterruptibly() throws InterruptedException {
615     Thread current = Thread.currentThread();
616 dl 1.7 if (Thread.interrupted() ||
617     (!canBarge() || !acquireOwner(current)) &&
618     !doLock(current, null, true, 0))
619     throw new InterruptedException();
620 dl 1.2 }
621 tim 1.1
622     /**
623     * Acquires the lock only if it is not held by another thread at the time
624     * of invocation.
625     * <p>Acquires the lock if it is not held by another thread and returns
626     * immediately with the value <tt>true</tt>, setting the lock hold count
627     * to one.
628     * <p> If the current thread
629     * already holds this lock then the hold count is incremented by one and
630 dl 1.5 * the method returns <tt>true</tt>.
631 tim 1.1 * <p>If the lock is held by another thread then this method will return
632     * immediately with the value <tt>false</tt>.
633     *
634     * @return <tt>true</tt>if the lock was free and was acquired by the
635     * current thread, or the lock was already held by the current thread; and
636     * <tt>false</tt> otherwise.
637     */
638     public boolean tryLock() {
639 dl 1.2 Thread current = Thread.currentThread();
640     if (acquireOwner(current))
641     return true;
642     if (owner == current) {
643     ++recursions;
644     return true;
645     }
646 tim 1.1 return false;
647     }
648    
649     /**
650     *
651     * Acquires the lock if it is not held by another thread within the given
652     * waiting time and the current thread has not been interrupted.
653     * <p>Acquires the lock if it is not held by another thread and returns
654     * immediately with the value <tt>true</tt>, setting the lock hold count
655     * to one.
656     * <p> If the current thread
657     * already holds this lock then the hold count is incremented by one and
658 dl 1.5 * the method returns <tt>true</tt>.
659 tim 1.1 * <p>If the lock is held by another thread then the
660     * the current thread becomes disabled for thread scheduling
661     * purposes and lies dormant until one of three things happens:
662     * <ul>
663     * <li> The lock is acquired by the current thread; or
664     * <li> Some other thread {@link Thread#interrupt interrupts} the current
665     * thread; or
666     * <li> The specified waiting time elapses
667     * </ul>
668     * <p>If the lock is acquired then the value <tt>true</tt> is returned and
669     * the lock hold count is set to one.
670     * <p>If the current thread:
671     * <ul>
672     * <li>has its interrupted status set on entry to this method; or
673 dl 1.2 * <li>is {@link Thread#interrupt interrupted} before acquiring
674 tim 1.1 * the lock,
675     * </ul>
676     * then {@link InterruptedException} is thrown and the current thread's
677     * interrupted status is cleared. As this method is an explicit
678     * interruption point, preference is given to responding to the interrupt
679     * over reentrant acquisition of the lock.
680     * <p>If the specified waiting time elapses then the value <tt>false</tt>
681     * is returned.
682     * <p>The given waiting time is a best-effort lower bound. If the time is
683     * less than or equal to zero, the method will not wait at all.
684     *
685     *
686     * @return <tt>true</tt> if the lock was free and was acquired by the
687     * current thread, or the lock was already held by the current thread; and
688     * <tt>false</tt> if the waiting time elapsed before the lock could be
689     * acquired.
690     *
691     * @throws InterruptedException if the current thread is interrupted
692     */
693 dl 1.2 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
694     if (unit == null)
695     throw new NullPointerException();
696     if (Thread.interrupted())
697     throw new InterruptedException();
698     Thread current = Thread.currentThread();
699     if (canBarge() && acquireOwner(current))
700     return true;
701 dl 1.6 if (owner == current) { // check recursions before timeout
702 dl 1.2 ++recursions;
703     return true;
704     }
705     if (timeout <= 0)
706     return false;
707 dl 1.6 if (doLock(current, null, true, unit.toNanos(timeout)))
708 dl 1.2 return true;
709 dl 1.6 if (Thread.interrupted())
710 dl 1.2 throw new InterruptedException();
711 dl 1.6 return false; // timed out
712 tim 1.1 }
713    
714    
715     /**
716     * Queries the number of holds on this lock by the current thread.
717     * <p>A thread has a hold on a lock for each lock action that is not
718     * matched by an unlock action.
719     * <p>The hold count information is typically only used for testing and
720     * debugging purposes. For example, if a certain section of code should
721     * not be entered with the lock already held then we can assert that
722     * fact:
723     * <pre>
724     * class X {
725     * ReentrantLock lock = new ReentrantLock();
726     * // ...
727     *
728     * public void m() {
729     * assert lock.getHoldCount() == 0;
730     * lock.lock();
731     * try {
732     * // ... method body
733     * } finally {
734     * lock.unlock()
735     * }
736     * }
737     * }
738     * </pre>
739     *
740     * @return the number of holds on this lock by current thread,
741     * or zero if this lock is not held by current thread.
742     **/
743     public int getHoldCount() {
744 dl 1.2 return (owner == Thread.currentThread()) ? recursions + 1 : 0;
745 tim 1.1 }
746    
747     /**
748     * Queries if this lock is held by the current thread.
749     * <p>Analogous to the {@link Thread#holdsLock} method for built-in
750     * monitor locks, this method is typically used for debugging and
751     * testing. For example, a method that should only be called while
752     * a lock is held can assert that this is the case:
753     * <pre>
754     * class X {
755     * ReentrantLock lock = new ReentrantLock();
756     * // ...
757     *
758     * public void m() {
759     * assert lock.isHeldByCurrentThread();
760     * // ... method body
761     * }
762     * }
763     * </pre>
764     *
765     * @return <tt>true</tt> if current thread holds this lock and
766     * <tt>false</tt> otherwise.
767     **/
768     public boolean isHeldByCurrentThread() {
769 dl 1.2 return (owner == Thread.currentThread());
770     }
771    
772    
773     /**
774     * Queries if this lock is held by any thread. THis method is
775     * designed for use in monitoring, not for synchronization control.
776     * @return <tt>true</tt> if any thread holds this lock and
777     * <tt>false</tt> otherwise.
778     **/
779     public boolean isLocked() {
780     return owner != null;
781 tim 1.1 }
782    
783 dl 1.3 /**
784     * Reconstitute by resetting head and tail to point back to the lock.
785     */
786     private void readObject(java.io.ObjectInputStream s)
787     throws java.io.IOException, ClassNotFoundException {
788     s.defaultReadObject();
789     head = tail = this;
790     }
791 dl 1.2
792 tim 1.1 /**
793     * Returns a {@link Condition} instance for use with this
794     * {@link Lock} instance.
795     *
796     * <p>The returned {@link Condition} instance has the same behavior and
797     * usage
798     * restrictions with this lock as the {@link Object} monitor methods
799     * ({@link Object#wait() wait}, {@link Object#notify notify}, and
800     * {@link Object#notifyAll notifyAll}) have with the built-in monitor
801     * lock:
802     * <ul>
803     * <li>If this lock is not held when any of the {@link Condition}
804     * {@link Condition#await() waiting} or {@link Condition#signal signalling}
805     * methods are called, then an {@link IllegalMonitorStateException} is
806     * thrown.
807     * <li>When the condition {@link Condition#await() waiting} methods are
808     * called the lock is released and before they return the lock is
809     * reacquired and the lock hold count restored to what it was when the
810     * method was called.
811     * <li>If a thread is {@link Thread#interrupt interrupted} while waiting
812     * then the wait will terminate, an {@link InterruptedException} will be
813     * thrown, and the thread's interrupted status will be cleared.
814     * <li>The order in which waiting threads are signalled is not specified.
815     * <li>The order in which threads returning from a wait, and threads trying
816     * to acquire the lock, are granted the lock, is not specified.
817     * </ul>
818     */
819     public Condition newCondition() {
820 dl 1.2 return new ReentrantLockConditionObject();
821     }
822    
823     // Helper methods for Conditions
824    
825     /**
826     * Return true if a node, always one that was initially placed on
827     * a condition queue, is off the condition queue (and thus,
828     * normally is now on lock queue.)
829     */
830 dl 1.3 boolean isOffConditionQueue(ReentrantLockQueueNode w) {
831     return w.releaseStatus > TRANSFERRING;
832 dl 1.2 }
833    
834     /**
835 dl 1.6 * Transfer a node from a condition queue onto lock queue.
836 dl 1.2 * Return true if successful (i.e., node not cancelled)
837     */
838 dl 1.3 final boolean transferToLockQueue(ReentrantLockQueueNode node) {
839 dl 1.2 /*
840     * Atomically change status to TRANSFERRING to avoid races
841     * with cancelling waiters. We use a special value that causes
842     * any waiters spuriously waking up to re-park until the node
843     * has been placed on lock queue.
844     */
845 dl 1.3 if (!casReleaseStatus(node, ON_CONDITION_QUEUE, TRANSFERRING))
846 dl 1.2 return false;
847    
848     /*
849     * Splice onto queue
850     */
851 dl 1.3 ReentrantLockQueueNode p = enq(node);
852 dl 1.2
853     /*
854 dl 1.3 * Establish normal lock-queue releaseStatus for node. The
855 dl 1.2 * CAS can fail if node already was involved in a cancellation
856     * on lock-queue, in which case we signal to be sure.
857     */
858 dl 1.3 if (!casReleaseStatus(node, TRANSFERRING, 0))
859 dl 1.2 signalSuccessor(node);
860    
861     /*
862 dl 1.3 * Ensure releaseStatus of predecessor is negative to indicate
863     * that thread is (probably) waiting. If attempt to set releaseStatus
864 dl 1.2 * fails or is pred is/becomes cancelled, wake up successor
865     * (which will ordinarily be "node") to resynch.
866     */
867    
868     for (;;) {
869 dl 1.3 int c = p.releaseStatus;
870     if (c < 0 || (c != CANCELLED && casReleaseStatus(p, c, -1)))
871 dl 1.2 break;
872     signalSuccessor(p);
873     if (c == CANCELLED)
874     break;
875     }
876    
877     return true;
878 tim 1.1 }
879    
880 dl 1.2 /**
881     * Hook method used by ReentrantReadWriteLock. Called
882     * before unlocking lock to enter wait.
883     */
884     void beforeWait() { }
885    
886    
887     /**
888     * Hook method used by ReentrantReadWriteLock. Called
889     * after locking lock after exiting wait.
890     */
891     void afterWait() { }
892    
893     private class ReentrantLockConditionObject implements Condition, java.io.Serializable {
894     /*
895     * Because condition queues are accessed only when locks are
896     * already held, we just need a simple linked queue to hold
897     * nodes while they are waiting on conditions. They are then
898     * transferred to the lock queue to re-acquire locks.
899     */
900    
901     /**
902     * First node of condition queue.
903     */
904 dl 1.3 private transient ReentrantLockQueueNode firstWaiter;
905 dl 1.2
906     /**
907     * Last node of condition queue.
908     */
909 dl 1.3 private transient ReentrantLockQueueNode lastWaiter;
910 dl 1.2
911     /**
912     * Basic linked queue insertion.
913     */
914 dl 1.3 private ReentrantLockQueueNode addWaiter(Thread current) {
915     ReentrantLockQueueNode w = new ReentrantLockQueueNode(current);
916     w.releaseStatus = ON_CONDITION_QUEUE;
917 dl 1.2 if (lastWaiter == null)
918     firstWaiter = lastWaiter = w;
919     else {
920 dl 1.3 ReentrantLockQueueNode t = lastWaiter;
921 dl 1.2 lastWaiter = w;
922     t.next = w;
923     }
924     return w;
925     }
926    
927     /**
928     * Main code for signal. Dequeue and transfer nodes until hit
929     * non-cancelled one or null. Split out from signal to
930     * encourage compilers to inline the case of no waiters.
931     */
932 dl 1.3 private void doSignal(ReentrantLockQueueNode first) {
933 dl 1.2 do {
934     if ( (firstWaiter = first.next) == null)
935     lastWaiter = null;
936     first.next = null;
937     if (transferToLockQueue(first))
938     return;
939     first = firstWaiter;
940     } while (first != null);
941     }
942    
943     public void signal() {
944     checkOwner(Thread.currentThread());
945 dl 1.3 ReentrantLockQueueNode w = firstWaiter;
946 dl 1.2 if (w != null)
947     doSignal(w);
948     }
949    
950     public void signalAll() {
951     checkOwner(Thread.currentThread());
952     // Pull off list all at once and traverse.
953 dl 1.3 ReentrantLockQueueNode w = firstWaiter;
954 dl 1.2 if (w != null) {
955     lastWaiter = firstWaiter = null;
956     do {
957 dl 1.3 ReentrantLockQueueNode n = w.next;
958 dl 1.2 w.next = null;
959     transferToLockQueue(w);
960     w = n;
961     } while (w != null);
962     }
963     }
964    
965     /*
966     * Various flavors of wait. Each almost the same, but
967     * annoyingly different and no nice way to factor common code.
968     */
969    
970     public void await() throws InterruptedException {
971     Thread current = Thread.currentThread();
972     checkOwner(current);
973    
974 dl 1.3 ReentrantLockQueueNode w = addWaiter(current);
975 dl 1.2 beforeWait();
976     int recs = recursions;
977     unlock();
978    
979     boolean wasInterrupted = false;
980    
981     while (!isOffConditionQueue(w)) {
982     JSR166Support.park(false, 0);
983     if (Thread.interrupted()) {
984     wasInterrupted = true;
985 dl 1.3 if (casReleaseStatus(w, ON_CONDITION_QUEUE, CANCELLED)) {
986 dl 1.2 w.thread = null;
987     w = null;
988     }
989     break;
990     }
991     }
992    
993     /*
994     * If we exited above loop due to cancellation, then w is
995     * null, and doLock will make a new lock node for
996     * us. Otherwise, upon exit, our node is already in the
997     * lock queue when doLock is called.
998     */
999 dl 1.6 doLock(current, w, false, 0);
1000 dl 1.2
1001     recursions = recs;
1002     afterWait();
1003    
1004 dl 1.6 if (wasInterrupted || Thread.interrupted())
1005 dl 1.2 throw new InterruptedException();
1006     }
1007    
1008     public void awaitUninterruptibly() {
1009     Thread current = Thread.currentThread();
1010     checkOwner(current);
1011    
1012 dl 1.3 ReentrantLockQueueNode w = addWaiter(current);
1013 dl 1.2 beforeWait();
1014     int recs = recursions;
1015     unlock();
1016    
1017     boolean wasInterrupted = false;
1018     while (!isOffConditionQueue(w)) {
1019     JSR166Support.park(false, 0);
1020     if (Thread.interrupted())
1021     wasInterrupted = true;
1022     }
1023    
1024 dl 1.6 doLock(current, w, false, 0);
1025 dl 1.2 recursions = recs;
1026     afterWait();
1027     // avoid re-interrupts on exit
1028     if (wasInterrupted && !current.isInterrupted())
1029     current.interrupt();
1030     }
1031    
1032    
1033     public long awaitNanos(long nanos) throws InterruptedException {
1034     Thread current = Thread.currentThread();
1035     checkOwner(current);
1036    
1037 dl 1.3 ReentrantLockQueueNode w = addWaiter(current);
1038 dl 1.2 beforeWait();
1039     int recs = recursions;
1040     unlock();
1041    
1042     if (nanos <= 0) nanos = 1; // park arg must be positive
1043     long timeLeft = nanos;
1044     long startTime = TimeUnit.nanoTime();
1045     boolean wasInterrupted = false;
1046     boolean cancelled = false;
1047    
1048     if (!isOffConditionQueue(w)) {
1049     for (;;) {
1050     JSR166Support.park(false, timeLeft);
1051     if (Thread.interrupted())
1052     wasInterrupted = true;
1053     else if (isOffConditionQueue(w))
1054     break;
1055     else
1056     timeLeft = nanos - (TimeUnit.nanoTime() - startTime);
1057    
1058     if (wasInterrupted || timeLeft <= 0) {
1059 dl 1.3 if (casReleaseStatus(w, ON_CONDITION_QUEUE, CANCELLED)) {
1060 dl 1.2 w.thread = null;
1061     w = null;
1062     }
1063     break;
1064     }
1065     }
1066     }
1067    
1068 dl 1.6 doLock(current, w, false, 0);
1069 dl 1.2 recursions = recs;
1070     afterWait();
1071    
1072 dl 1.6 if (wasInterrupted || Thread.interrupted())
1073 dl 1.2 throw new InterruptedException();
1074     else if (timeLeft <= 0)
1075     return timeLeft;
1076     else
1077     return nanos - (TimeUnit.nanoTime() - startTime);
1078     }
1079    
1080     public boolean awaitUntil(Date deadline) throws InterruptedException {
1081     Thread current = Thread.currentThread();
1082     checkOwner(current);
1083    
1084 dl 1.3 ReentrantLockQueueNode w = addWaiter(current);
1085 dl 1.2 beforeWait();
1086     int recs = recursions;
1087     unlock();
1088    
1089     boolean wasInterrupted = false;
1090     boolean cancelled = false;
1091     long abstime = deadline.getTime();
1092    
1093     if (!isOffConditionQueue(w)) {
1094     for (;;) {
1095     JSR166Support.park(true, abstime);
1096    
1097     boolean timedOut = false;
1098     if (Thread.interrupted())
1099     wasInterrupted = true;
1100     else if (isOffConditionQueue(w))
1101     break;
1102     else if (System.currentTimeMillis() <= abstime)
1103     timedOut = true;
1104    
1105     if (wasInterrupted || timedOut) {
1106 dl 1.3 if (casReleaseStatus(w, ON_CONDITION_QUEUE, CANCELLED)) {
1107 dl 1.2 w.thread = null;
1108     w = null;
1109     }
1110     break;
1111     }
1112     }
1113     }
1114 tim 1.1
1115 dl 1.6 doLock(current, w, false, 0);
1116 dl 1.2 recursions = recs;
1117     afterWait();
1118 tim 1.1
1119 dl 1.6 if (wasInterrupted || Thread.interrupted())
1120 dl 1.2 throw new InterruptedException();
1121     return !cancelled;
1122     }
1123 tim 1.1
1124 dl 1.2 public boolean await(long time, TimeUnit unit) throws InterruptedException {
1125     return awaitNanos(unit.toNanos(time)) > 0;
1126     }
1127 tim 1.1
1128 dl 1.2 }
1129    
1130 dl 1.3 }
1131    
1132     /**
1133     * Node class for threads waiting for locks. This cannot be nested
1134     * inside ReentrantLock because of Java inheritance circularity rules.
1135     */
1136     class ReentrantLockQueueNode {
1137     /**
1138     * Controls whether successor node is allowed to try to obtain
1139     * ownership. Acts as a saturating (in both directions) counting
1140     * semaphore: Upon each wait, the releaseStatus is reduced to zero
1141     * if positive, else reduced to negative, in which case the thread
1142     * will park. The releaseStatus is incremented on each unlock that
1143     * would enable successor thread to obtain lock (succeeding if
1144     * there is no contention). The special value of CANCELLED is used
1145     * to mean that the releaseStatus cannot be either incremented or
1146     * decremented. The special value of ON_CONDITION_QUEUE is used
1147     * when nodes are on conditions queues instead of lock queue, and
1148     * the special value TRANSFERRING is used while signals are in
1149     * progress.
1150     */
1151     transient volatile int releaseStatus;
1152    
1153     /**
1154     * Link to predecessor node that current node/thread relies on
1155     * for checking releaseStatus. Assigned once during enqueing,
1156     * and nulled out (for sake of GC) only upon dequeuing. Upon
1157     * cancellation, we do NOT adjust this field, but simply
1158     * traverse through prev's until we hit a non-cancelled node.
1159     * A valid predecessor will always exist because the head node
1160     * is never cancelled.
1161     */
1162     transient volatile ReentrantLockQueueNode prev;
1163    
1164     /**
1165     * Link to the successor node that the current node/thread
1166     * unparks upon lock release. Assigned once during enquing.
1167     * Upon cancellation, we do NOT adjust this field, but simply
1168     * traverse through next's until we hit a non-cancelled node,
1169     * (or null if at end of queue). The enqueue operation does
1170     * not assign next field of a predecessor until after
1171     * attachment, so seeing a null next field not necessarily
1172     * mean that node is at end of queue. However, if a next field
1173     * appears to be null, we can scan prev's from the tail to
1174     * double-check.
1175     */
1176     transient volatile ReentrantLockQueueNode next;
1177    
1178     /**
1179     * The thread that enqueued this node. Initialized on
1180     * construction and nulled out after use. Note that this need
1181     * not be declared volatile since it is always accessed after
1182     * traversing volatile links, and written before writing
1183     * links.
1184     */
1185     transient Thread thread;
1186    
1187     ReentrantLockQueueNode() { }
1188     ReentrantLockQueueNode(Thread t) { thread = t; }
1189 dl 1.2 }