1/*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9package jsr166;
10
11import static java.util.concurrent.TimeUnit.MILLISECONDS;
12
13import java.util.Arrays;
14import java.util.Collection;
15import java.util.HashSet;
16import java.util.concurrent.CountDownLatch;
17import java.util.concurrent.CyclicBarrier;
18import java.util.concurrent.locks.Condition;
19import java.util.concurrent.locks.ReentrantLock;
20
21import junit.framework.AssertionFailedError;
22import junit.framework.Test;
23import junit.framework.TestSuite;
24
25public class ReentrantLockTest extends JSR166TestCase {
26    // android-note: Removed because the CTS runner does a bad job of
27    // retrying tests that have suite() declarations.
28    //
29    // public static void main(String[] args) {
30    //     main(suite(), args);
31    // }
32    // public static Test suite() {
33    //     return new TestSuite(ReentrantLockTest.class);
34    // }
35
36    /**
37     * A checked runnable calling lockInterruptibly
38     */
39    class InterruptibleLockRunnable extends CheckedRunnable {
40        final ReentrantLock lock;
41        InterruptibleLockRunnable(ReentrantLock lock) { this.lock = lock; }
42        public void realRun() throws InterruptedException {
43            lock.lockInterruptibly();
44        }
45    }
46
47    /**
48     * A checked runnable calling lockInterruptibly that expects to be
49     * interrupted
50     */
51    class InterruptedLockRunnable extends CheckedInterruptedRunnable {
52        final ReentrantLock lock;
53        InterruptedLockRunnable(ReentrantLock lock) { this.lock = lock; }
54        public void realRun() throws InterruptedException {
55            lock.lockInterruptibly();
56        }
57    }
58
59    /**
60     * Subclass to expose protected methods
61     */
62    static class PublicReentrantLock extends ReentrantLock {
63        PublicReentrantLock() { super(); }
64        PublicReentrantLock(boolean fair) { super(fair); }
65        public Thread getOwner() {
66            return super.getOwner();
67        }
68        public Collection<Thread> getQueuedThreads() {
69            return super.getQueuedThreads();
70        }
71        public Collection<Thread> getWaitingThreads(Condition c) {
72            return super.getWaitingThreads(c);
73        }
74    }
75
76    /**
77     * Releases write lock, checking that it had a hold count of 1.
78     */
79    void releaseLock(PublicReentrantLock lock) {
80        assertLockedByMoi(lock);
81        lock.unlock();
82        assertFalse(lock.isHeldByCurrentThread());
83        assertNotLocked(lock);
84    }
85
86    /**
87     * Spin-waits until lock.hasQueuedThread(t) becomes true.
88     */
89    void waitForQueuedThread(PublicReentrantLock lock, Thread t) {
90        long startTime = System.nanoTime();
91        while (!lock.hasQueuedThread(t)) {
92            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
93                throw new AssertionFailedError("timed out");
94            Thread.yield();
95        }
96        assertTrue(t.isAlive());
97        assertNotSame(t, lock.getOwner());
98    }
99
100    /**
101     * Checks that lock is not locked.
102     */
103    void assertNotLocked(PublicReentrantLock lock) {
104        assertFalse(lock.isLocked());
105        assertFalse(lock.isHeldByCurrentThread());
106        assertNull(lock.getOwner());
107        assertEquals(0, lock.getHoldCount());
108    }
109
110    /**
111     * Checks that lock is locked by the given thread.
112     */
113    void assertLockedBy(PublicReentrantLock lock, Thread t) {
114        assertTrue(lock.isLocked());
115        assertSame(t, lock.getOwner());
116        assertEquals(t == Thread.currentThread(),
117                     lock.isHeldByCurrentThread());
118        assertEquals(t == Thread.currentThread(),
119                     lock.getHoldCount() > 0);
120    }
121
122    /**
123     * Checks that lock is locked by the current thread.
124     */
125    void assertLockedByMoi(PublicReentrantLock lock) {
126        assertLockedBy(lock, Thread.currentThread());
127    }
128
129    /**
130     * Checks that condition c has no waiters.
131     */
132    void assertHasNoWaiters(PublicReentrantLock lock, Condition c) {
133        assertHasWaiters(lock, c, new Thread[] {});
134    }
135
136    /**
137     * Checks that condition c has exactly the given waiter threads.
138     */
139    void assertHasWaiters(PublicReentrantLock lock, Condition c,
140                          Thread... threads) {
141        lock.lock();
142        assertEquals(threads.length > 0, lock.hasWaiters(c));
143        assertEquals(threads.length, lock.getWaitQueueLength(c));
144        assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
145        assertEquals(threads.length, lock.getWaitingThreads(c).size());
146        assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
147                     new HashSet<Thread>(Arrays.asList(threads)));
148        lock.unlock();
149    }
150
151    enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
152
153    /**
154     * Awaits condition "indefinitely" using the specified AwaitMethod.
155     */
156    void await(Condition c, AwaitMethod awaitMethod)
157            throws InterruptedException {
158        long timeoutMillis = 2 * LONG_DELAY_MS;
159        switch (awaitMethod) {
160        case await:
161            c.await();
162            break;
163        case awaitTimed:
164            assertTrue(c.await(timeoutMillis, MILLISECONDS));
165            break;
166        case awaitNanos:
167            long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
168            long nanosRemaining = c.awaitNanos(timeoutNanos);
169            assertTrue(nanosRemaining > timeoutNanos / 2);
170            assertTrue(nanosRemaining <= timeoutNanos);
171            break;
172        case awaitUntil:
173            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
174            break;
175        default:
176            throw new AssertionError();
177        }
178    }
179
180    /**
181     * Constructor sets given fairness, and is in unlocked state
182     */
183    public void testConstructor() {
184        PublicReentrantLock lock;
185
186        lock = new PublicReentrantLock();
187        assertFalse(lock.isFair());
188        assertNotLocked(lock);
189
190        lock = new PublicReentrantLock(true);
191        assertTrue(lock.isFair());
192        assertNotLocked(lock);
193
194        lock = new PublicReentrantLock(false);
195        assertFalse(lock.isFair());
196        assertNotLocked(lock);
197    }
198
199    /**
200     * locking an unlocked lock succeeds
201     */
202    public void testLock()      { testLock(false); }
203    public void testLock_fair() { testLock(true); }
204    public void testLock(boolean fair) {
205        PublicReentrantLock lock = new PublicReentrantLock(fair);
206        lock.lock();
207        assertLockedByMoi(lock);
208        releaseLock(lock);
209    }
210
211    /**
212     * Unlocking an unlocked lock throws IllegalMonitorStateException
213     */
214    public void testUnlock_IMSE()      { testUnlock_IMSE(false); }
215    public void testUnlock_IMSE_fair() { testUnlock_IMSE(true); }
216    public void testUnlock_IMSE(boolean fair) {
217        ReentrantLock lock = new ReentrantLock(fair);
218        try {
219            lock.unlock();
220            shouldThrow();
221        } catch (IllegalMonitorStateException success) {}
222    }
223
224    /**
225     * tryLock on an unlocked lock succeeds
226     */
227    public void testTryLock()      { testTryLock(false); }
228    public void testTryLock_fair() { testTryLock(true); }
229    public void testTryLock(boolean fair) {
230        PublicReentrantLock lock = new PublicReentrantLock(fair);
231        assertTrue(lock.tryLock());
232        assertLockedByMoi(lock);
233        assertTrue(lock.tryLock());
234        assertLockedByMoi(lock);
235        lock.unlock();
236        releaseLock(lock);
237    }
238
239    /**
240     * hasQueuedThreads reports whether there are waiting threads
241     */
242    public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
243    public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
244    public void testHasQueuedThreads(boolean fair) {
245        final PublicReentrantLock lock = new PublicReentrantLock(fair);
246        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
247        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
248        assertFalse(lock.hasQueuedThreads());
249        lock.lock();
250        assertFalse(lock.hasQueuedThreads());
251        t1.start();
252        waitForQueuedThread(lock, t1);
253        assertTrue(lock.hasQueuedThreads());
254        t2.start();
255        waitForQueuedThread(lock, t2);
256        assertTrue(lock.hasQueuedThreads());
257        t1.interrupt();
258        awaitTermination(t1);
259        assertTrue(lock.hasQueuedThreads());
260        lock.unlock();
261        awaitTermination(t2);
262        assertFalse(lock.hasQueuedThreads());
263    }
264
265    /**
266     * getQueueLength reports number of waiting threads
267     */
268    public void testGetQueueLength()      { testGetQueueLength(false); }
269    public void testGetQueueLength_fair() { testGetQueueLength(true); }
270    public void testGetQueueLength(boolean fair) {
271        final PublicReentrantLock lock = new PublicReentrantLock(fair);
272        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
273        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
274        assertEquals(0, lock.getQueueLength());
275        lock.lock();
276        t1.start();
277        waitForQueuedThread(lock, t1);
278        assertEquals(1, lock.getQueueLength());
279        t2.start();
280        waitForQueuedThread(lock, t2);
281        assertEquals(2, lock.getQueueLength());
282        t1.interrupt();
283        awaitTermination(t1);
284        assertEquals(1, lock.getQueueLength());
285        lock.unlock();
286        awaitTermination(t2);
287        assertEquals(0, lock.getQueueLength());
288    }
289
290    /**
291     * hasQueuedThread(null) throws NPE
292     */
293    public void testHasQueuedThreadNPE()      { testHasQueuedThreadNPE(false); }
294    public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
295    public void testHasQueuedThreadNPE(boolean fair) {
296        final ReentrantLock lock = new ReentrantLock(fair);
297        try {
298            lock.hasQueuedThread(null);
299            shouldThrow();
300        } catch (NullPointerException success) {}
301    }
302
303    /**
304     * hasQueuedThread reports whether a thread is queued
305     */
306    public void testHasQueuedThread()      { testHasQueuedThread(false); }
307    public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
308    public void testHasQueuedThread(boolean fair) {
309        final PublicReentrantLock lock = new PublicReentrantLock(fair);
310        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
311        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
312        assertFalse(lock.hasQueuedThread(t1));
313        assertFalse(lock.hasQueuedThread(t2));
314        lock.lock();
315        t1.start();
316        waitForQueuedThread(lock, t1);
317        assertTrue(lock.hasQueuedThread(t1));
318        assertFalse(lock.hasQueuedThread(t2));
319        t2.start();
320        waitForQueuedThread(lock, t2);
321        assertTrue(lock.hasQueuedThread(t1));
322        assertTrue(lock.hasQueuedThread(t2));
323        t1.interrupt();
324        awaitTermination(t1);
325        assertFalse(lock.hasQueuedThread(t1));
326        assertTrue(lock.hasQueuedThread(t2));
327        lock.unlock();
328        awaitTermination(t2);
329        assertFalse(lock.hasQueuedThread(t1));
330        assertFalse(lock.hasQueuedThread(t2));
331    }
332
333    /**
334     * getQueuedThreads includes waiting threads
335     */
336    public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
337    public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
338    public void testGetQueuedThreads(boolean fair) {
339        final PublicReentrantLock lock = new PublicReentrantLock(fair);
340        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
341        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
342        assertTrue(lock.getQueuedThreads().isEmpty());
343        lock.lock();
344        assertTrue(lock.getQueuedThreads().isEmpty());
345        t1.start();
346        waitForQueuedThread(lock, t1);
347        assertEquals(1, lock.getQueuedThreads().size());
348        assertTrue(lock.getQueuedThreads().contains(t1));
349        t2.start();
350        waitForQueuedThread(lock, t2);
351        assertEquals(2, lock.getQueuedThreads().size());
352        assertTrue(lock.getQueuedThreads().contains(t1));
353        assertTrue(lock.getQueuedThreads().contains(t2));
354        t1.interrupt();
355        awaitTermination(t1);
356        assertFalse(lock.getQueuedThreads().contains(t1));
357        assertTrue(lock.getQueuedThreads().contains(t2));
358        assertEquals(1, lock.getQueuedThreads().size());
359        lock.unlock();
360        awaitTermination(t2);
361        assertTrue(lock.getQueuedThreads().isEmpty());
362    }
363
364    /**
365     * timed tryLock is interruptible
366     */
367    public void testTryLock_Interruptible()      { testTryLock_Interruptible(false); }
368    public void testTryLock_Interruptible_fair() { testTryLock_Interruptible(true); }
369    public void testTryLock_Interruptible(boolean fair) {
370        final PublicReentrantLock lock = new PublicReentrantLock(fair);
371        lock.lock();
372        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
373            public void realRun() throws InterruptedException {
374                lock.tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
375            }});
376
377        waitForQueuedThread(lock, t);
378        t.interrupt();
379        awaitTermination(t);
380        releaseLock(lock);
381    }
382
383    /**
384     * tryLock on a locked lock fails
385     */
386    public void testTryLockWhenLocked()      { testTryLockWhenLocked(false); }
387    public void testTryLockWhenLocked_fair() { testTryLockWhenLocked(true); }
388    public void testTryLockWhenLocked(boolean fair) {
389        final PublicReentrantLock lock = new PublicReentrantLock(fair);
390        lock.lock();
391        Thread t = newStartedThread(new CheckedRunnable() {
392            public void realRun() {
393                assertFalse(lock.tryLock());
394            }});
395
396        awaitTermination(t);
397        releaseLock(lock);
398    }
399
400    /**
401     * Timed tryLock on a locked lock times out
402     */
403    public void testTryLock_Timeout()      { testTryLock_Timeout(false); }
404    public void testTryLock_Timeout_fair() { testTryLock_Timeout(true); }
405    public void testTryLock_Timeout(boolean fair) {
406        final PublicReentrantLock lock = new PublicReentrantLock(fair);
407        lock.lock();
408        Thread t = newStartedThread(new CheckedRunnable() {
409            public void realRun() throws InterruptedException {
410                long startTime = System.nanoTime();
411                long timeoutMillis = 10;
412                assertFalse(lock.tryLock(timeoutMillis, MILLISECONDS));
413                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
414            }});
415
416        awaitTermination(t);
417        releaseLock(lock);
418    }
419
420    /**
421     * getHoldCount returns number of recursive holds
422     */
423    public void testGetHoldCount()      { testGetHoldCount(false); }
424    public void testGetHoldCount_fair() { testGetHoldCount(true); }
425    public void testGetHoldCount(boolean fair) {
426        ReentrantLock lock = new ReentrantLock(fair);
427        for (int i = 1; i <= SIZE; i++) {
428            lock.lock();
429            assertEquals(i, lock.getHoldCount());
430        }
431        for (int i = SIZE; i > 0; i--) {
432            lock.unlock();
433            assertEquals(i - 1, lock.getHoldCount());
434        }
435    }
436
437    /**
438     * isLocked is true when locked and false when not
439     */
440    public void testIsLocked()      { testIsLocked(false); }
441    public void testIsLocked_fair() { testIsLocked(true); }
442    public void testIsLocked(boolean fair) {
443        try {
444            final ReentrantLock lock = new ReentrantLock(fair);
445            assertFalse(lock.isLocked());
446            lock.lock();
447            assertTrue(lock.isLocked());
448            lock.lock();
449            assertTrue(lock.isLocked());
450            lock.unlock();
451            assertTrue(lock.isLocked());
452            lock.unlock();
453            assertFalse(lock.isLocked());
454            final CyclicBarrier barrier = new CyclicBarrier(2);
455            Thread t = newStartedThread(new CheckedRunnable() {
456                    public void realRun() throws Exception {
457                        lock.lock();
458                        assertTrue(lock.isLocked());
459                        barrier.await();
460                        barrier.await();
461                        lock.unlock();
462                    }});
463
464            barrier.await();
465            assertTrue(lock.isLocked());
466            barrier.await();
467            awaitTermination(t);
468            assertFalse(lock.isLocked());
469        } catch (Exception fail) { threadUnexpectedException(fail); }
470    }
471
472    /**
473     * lockInterruptibly succeeds when unlocked, else is interruptible
474     */
475    public void testLockInterruptibly()      { testLockInterruptibly(false); }
476    public void testLockInterruptibly_fair() { testLockInterruptibly(true); }
477    public void testLockInterruptibly(boolean fair) {
478        final PublicReentrantLock lock = new PublicReentrantLock(fair);
479        try {
480            lock.lockInterruptibly();
481        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
482        assertLockedByMoi(lock);
483        Thread t = newStartedThread(new InterruptedLockRunnable(lock));
484        waitForQueuedThread(lock, t);
485        t.interrupt();
486        assertTrue(lock.isLocked());
487        assertTrue(lock.isHeldByCurrentThread());
488        awaitTermination(t);
489        releaseLock(lock);
490    }
491
492    /**
493     * Calling await without holding lock throws IllegalMonitorStateException
494     */
495    public void testAwait_IMSE()      { testAwait_IMSE(false); }
496    public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
497    public void testAwait_IMSE(boolean fair) {
498        final ReentrantLock lock = new ReentrantLock(fair);
499        final Condition c = lock.newCondition();
500        for (AwaitMethod awaitMethod : AwaitMethod.values()) {
501            long startTime = System.nanoTime();
502            try {
503                await(c, awaitMethod);
504                shouldThrow();
505            } catch (IllegalMonitorStateException success) {
506            } catch (InterruptedException e) { threadUnexpectedException(e); }
507            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
508        }
509    }
510
511    /**
512     * Calling signal without holding lock throws IllegalMonitorStateException
513     */
514    public void testSignal_IMSE()      { testSignal_IMSE(false); }
515    public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
516    public void testSignal_IMSE(boolean fair) {
517        final ReentrantLock lock = new ReentrantLock(fair);
518        final Condition c = lock.newCondition();
519        try {
520            c.signal();
521            shouldThrow();
522        } catch (IllegalMonitorStateException success) {}
523    }
524
525    /**
526     * awaitNanos without a signal times out
527     */
528    public void testAwaitNanos_Timeout()      { testAwaitNanos_Timeout(false); }
529    public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
530    public void testAwaitNanos_Timeout(boolean fair) {
531        try {
532            final ReentrantLock lock = new ReentrantLock(fair);
533            final Condition c = lock.newCondition();
534            lock.lock();
535            long startTime = System.nanoTime();
536            long timeoutMillis = 10;
537            long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
538            long nanosRemaining = c.awaitNanos(timeoutNanos);
539            assertTrue(nanosRemaining <= 0);
540            assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
541            lock.unlock();
542        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
543    }
544
545    /**
546     * timed await without a signal times out
547     */
548    public void testAwait_Timeout()      { testAwait_Timeout(false); }
549    public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
550    public void testAwait_Timeout(boolean fair) {
551        try {
552            final ReentrantLock lock = new ReentrantLock(fair);
553            final Condition c = lock.newCondition();
554            lock.lock();
555            long startTime = System.nanoTime();
556            long timeoutMillis = 10;
557            assertFalse(c.await(timeoutMillis, MILLISECONDS));
558            assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
559            lock.unlock();
560        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
561    }
562
563    /**
564     * awaitUntil without a signal times out
565     */
566    public void testAwaitUntil_Timeout()      { testAwaitUntil_Timeout(false); }
567    public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
568    public void testAwaitUntil_Timeout(boolean fair) {
569        try {
570            final ReentrantLock lock = new ReentrantLock(fair);
571            final Condition c = lock.newCondition();
572            lock.lock();
573            // We shouldn't assume that nanoTime and currentTimeMillis
574            // use the same time source, so don't use nanoTime here.
575            java.util.Date delayedDate = delayedDate(timeoutMillis());
576            assertFalse(c.awaitUntil(delayedDate));
577            assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
578            lock.unlock();
579        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
580    }
581
582    /**
583     * await returns when signalled
584     */
585    public void testAwait()      { testAwait(false); }
586    public void testAwait_fair() { testAwait(true); }
587    public void testAwait(boolean fair) {
588        final PublicReentrantLock lock = new PublicReentrantLock(fair);
589        final Condition c = lock.newCondition();
590        final CountDownLatch locked = new CountDownLatch(1);
591        Thread t = newStartedThread(new CheckedRunnable() {
592            public void realRun() throws InterruptedException {
593                lock.lock();
594                locked.countDown();
595                c.await();
596                lock.unlock();
597            }});
598
599        await(locked);
600        lock.lock();
601        assertHasWaiters(lock, c, t);
602        c.signal();
603        assertHasNoWaiters(lock, c);
604        assertTrue(t.isAlive());
605        lock.unlock();
606        awaitTermination(t);
607    }
608
609    /**
610     * hasWaiters throws NPE if null
611     */
612    public void testHasWaitersNPE()      { testHasWaitersNPE(false); }
613    public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
614    public void testHasWaitersNPE(boolean fair) {
615        final ReentrantLock lock = new ReentrantLock(fair);
616        try {
617            lock.hasWaiters(null);
618            shouldThrow();
619        } catch (NullPointerException success) {}
620    }
621
622    /**
623     * getWaitQueueLength throws NPE if null
624     */
625    public void testGetWaitQueueLengthNPE()      { testGetWaitQueueLengthNPE(false); }
626    public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
627    public void testGetWaitQueueLengthNPE(boolean fair) {
628        final ReentrantLock lock = new ReentrantLock(fair);
629        try {
630            lock.getWaitQueueLength(null);
631            shouldThrow();
632        } catch (NullPointerException success) {}
633    }
634
635    /**
636     * getWaitingThreads throws NPE if null
637     */
638    public void testGetWaitingThreadsNPE()      { testGetWaitingThreadsNPE(false); }
639    public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
640    public void testGetWaitingThreadsNPE(boolean fair) {
641        final PublicReentrantLock lock = new PublicReentrantLock(fair);
642        try {
643            lock.getWaitingThreads(null);
644            shouldThrow();
645        } catch (NullPointerException success) {}
646    }
647
648    /**
649     * hasWaiters throws IllegalArgumentException if not owned
650     */
651    public void testHasWaitersIAE()      { testHasWaitersIAE(false); }
652    public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
653    public void testHasWaitersIAE(boolean fair) {
654        final ReentrantLock lock = new ReentrantLock(fair);
655        final Condition c = lock.newCondition();
656        final ReentrantLock lock2 = new ReentrantLock(fair);
657        try {
658            lock2.hasWaiters(c);
659            shouldThrow();
660        } catch (IllegalArgumentException success) {}
661    }
662
663    /**
664     * hasWaiters throws IllegalMonitorStateException if not locked
665     */
666    public void testHasWaitersIMSE()      { testHasWaitersIMSE(false); }
667    public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
668    public void testHasWaitersIMSE(boolean fair) {
669        final ReentrantLock lock = new ReentrantLock(fair);
670        final Condition c = lock.newCondition();
671        try {
672            lock.hasWaiters(c);
673            shouldThrow();
674        } catch (IllegalMonitorStateException success) {}
675    }
676
677    /**
678     * getWaitQueueLength throws IllegalArgumentException if not owned
679     */
680    public void testGetWaitQueueLengthIAE()      { testGetWaitQueueLengthIAE(false); }
681    public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
682    public void testGetWaitQueueLengthIAE(boolean fair) {
683        final ReentrantLock lock = new ReentrantLock(fair);
684        final Condition c = lock.newCondition();
685        final ReentrantLock lock2 = new ReentrantLock(fair);
686        try {
687            lock2.getWaitQueueLength(c);
688            shouldThrow();
689        } catch (IllegalArgumentException success) {}
690    }
691
692    /**
693     * getWaitQueueLength throws IllegalMonitorStateException if not locked
694     */
695    public void testGetWaitQueueLengthIMSE()      { testGetWaitQueueLengthIMSE(false); }
696    public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
697    public void testGetWaitQueueLengthIMSE(boolean fair) {
698        final ReentrantLock lock = new ReentrantLock(fair);
699        final Condition c = lock.newCondition();
700        try {
701            lock.getWaitQueueLength(c);
702            shouldThrow();
703        } catch (IllegalMonitorStateException success) {}
704    }
705
706    /**
707     * getWaitingThreads throws IllegalArgumentException if not owned
708     */
709    public void testGetWaitingThreadsIAE()      { testGetWaitingThreadsIAE(false); }
710    public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
711    public void testGetWaitingThreadsIAE(boolean fair) {
712        final PublicReentrantLock lock = new PublicReentrantLock(fair);
713        final Condition c = lock.newCondition();
714        final PublicReentrantLock lock2 = new PublicReentrantLock(fair);
715        try {
716            lock2.getWaitingThreads(c);
717            shouldThrow();
718        } catch (IllegalArgumentException success) {}
719    }
720
721    /**
722     * getWaitingThreads throws IllegalMonitorStateException if not locked
723     */
724    public void testGetWaitingThreadsIMSE()      { testGetWaitingThreadsIMSE(false); }
725    public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
726    public void testGetWaitingThreadsIMSE(boolean fair) {
727        final PublicReentrantLock lock = new PublicReentrantLock(fair);
728        final Condition c = lock.newCondition();
729        try {
730            lock.getWaitingThreads(c);
731            shouldThrow();
732        } catch (IllegalMonitorStateException success) {}
733    }
734
735    /**
736     * hasWaiters returns true when a thread is waiting, else false
737     */
738    public void testHasWaiters()      { testHasWaiters(false); }
739    public void testHasWaiters_fair() { testHasWaiters(true); }
740    public void testHasWaiters(boolean fair) {
741        final PublicReentrantLock lock = new PublicReentrantLock(fair);
742        final Condition c = lock.newCondition();
743        final CountDownLatch pleaseSignal = new CountDownLatch(1);
744        Thread t = newStartedThread(new CheckedRunnable() {
745            public void realRun() throws InterruptedException {
746                lock.lock();
747                assertHasNoWaiters(lock, c);
748                assertFalse(lock.hasWaiters(c));
749                pleaseSignal.countDown();
750                c.await();
751                assertHasNoWaiters(lock, c);
752                assertFalse(lock.hasWaiters(c));
753                lock.unlock();
754            }});
755
756        await(pleaseSignal);
757        lock.lock();
758        assertHasWaiters(lock, c, t);
759        assertTrue(lock.hasWaiters(c));
760        c.signal();
761        assertHasNoWaiters(lock, c);
762        assertFalse(lock.hasWaiters(c));
763        lock.unlock();
764        awaitTermination(t);
765        assertHasNoWaiters(lock, c);
766    }
767
768    /**
769     * getWaitQueueLength returns number of waiting threads
770     */
771    public void testGetWaitQueueLength()      { testGetWaitQueueLength(false); }
772    public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
773    public void testGetWaitQueueLength(boolean fair) {
774        final PublicReentrantLock lock = new PublicReentrantLock(fair);
775        final Condition c = lock.newCondition();
776        final CountDownLatch locked1 = new CountDownLatch(1);
777        final CountDownLatch locked2 = new CountDownLatch(1);
778        Thread t1 = new Thread(new CheckedRunnable() {
779            public void realRun() throws InterruptedException {
780                lock.lock();
781                assertFalse(lock.hasWaiters(c));
782                assertEquals(0, lock.getWaitQueueLength(c));
783                locked1.countDown();
784                c.await();
785                lock.unlock();
786            }});
787
788        Thread t2 = new Thread(new CheckedRunnable() {
789            public void realRun() throws InterruptedException {
790                lock.lock();
791                assertTrue(lock.hasWaiters(c));
792                assertEquals(1, lock.getWaitQueueLength(c));
793                locked2.countDown();
794                c.await();
795                lock.unlock();
796            }});
797
798        lock.lock();
799        assertEquals(0, lock.getWaitQueueLength(c));
800        lock.unlock();
801
802        t1.start();
803        await(locked1);
804
805        lock.lock();
806        assertHasWaiters(lock, c, t1);
807        assertEquals(1, lock.getWaitQueueLength(c));
808        lock.unlock();
809
810        t2.start();
811        await(locked2);
812
813        lock.lock();
814        assertHasWaiters(lock, c, t1, t2);
815        assertEquals(2, lock.getWaitQueueLength(c));
816        c.signalAll();
817        assertHasNoWaiters(lock, c);
818        lock.unlock();
819
820        awaitTermination(t1);
821        awaitTermination(t2);
822
823        assertHasNoWaiters(lock, c);
824    }
825
826    /**
827     * getWaitingThreads returns only and all waiting threads
828     */
829    public void testGetWaitingThreads()      { testGetWaitingThreads(false); }
830    public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
831    public void testGetWaitingThreads(boolean fair) {
832        final PublicReentrantLock lock = new PublicReentrantLock(fair);
833        final Condition c = lock.newCondition();
834        final CountDownLatch locked1 = new CountDownLatch(1);
835        final CountDownLatch locked2 = new CountDownLatch(1);
836        Thread t1 = new Thread(new CheckedRunnable() {
837            public void realRun() throws InterruptedException {
838                lock.lock();
839                assertTrue(lock.getWaitingThreads(c).isEmpty());
840                locked1.countDown();
841                c.await();
842                lock.unlock();
843            }});
844
845        Thread t2 = new Thread(new CheckedRunnable() {
846            public void realRun() throws InterruptedException {
847                lock.lock();
848                assertFalse(lock.getWaitingThreads(c).isEmpty());
849                locked2.countDown();
850                c.await();
851                lock.unlock();
852            }});
853
854        lock.lock();
855        assertTrue(lock.getWaitingThreads(c).isEmpty());
856        lock.unlock();
857
858        t1.start();
859        await(locked1);
860
861        lock.lock();
862        assertHasWaiters(lock, c, t1);
863        assertTrue(lock.getWaitingThreads(c).contains(t1));
864        assertFalse(lock.getWaitingThreads(c).contains(t2));
865        assertEquals(1, lock.getWaitingThreads(c).size());
866        lock.unlock();
867
868        t2.start();
869        await(locked2);
870
871        lock.lock();
872        assertHasWaiters(lock, c, t1, t2);
873        assertTrue(lock.getWaitingThreads(c).contains(t1));
874        assertTrue(lock.getWaitingThreads(c).contains(t2));
875        assertEquals(2, lock.getWaitingThreads(c).size());
876        c.signalAll();
877        assertHasNoWaiters(lock, c);
878        lock.unlock();
879
880        awaitTermination(t1);
881        awaitTermination(t2);
882
883        assertHasNoWaiters(lock, c);
884    }
885
886    /**
887     * awaitUninterruptibly is uninterruptible
888     */
889    public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
890    public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
891    public void testAwaitUninterruptibly(boolean fair) {
892        final ReentrantLock lock = new ReentrantLock(fair);
893        final Condition c = lock.newCondition();
894        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
895
896        Thread t1 = newStartedThread(new CheckedRunnable() {
897            public void realRun() {
898                // Interrupt before awaitUninterruptibly
899                lock.lock();
900                pleaseInterrupt.countDown();
901                Thread.currentThread().interrupt();
902                c.awaitUninterruptibly();
903                assertTrue(Thread.interrupted());
904                lock.unlock();
905            }});
906
907        Thread t2 = newStartedThread(new CheckedRunnable() {
908            public void realRun() {
909                // Interrupt during awaitUninterruptibly
910                lock.lock();
911                pleaseInterrupt.countDown();
912                c.awaitUninterruptibly();
913                assertTrue(Thread.interrupted());
914                lock.unlock();
915            }});
916
917        await(pleaseInterrupt);
918        lock.lock();
919        lock.unlock();
920        t2.interrupt();
921
922        assertThreadStaysAlive(t1);
923        assertTrue(t2.isAlive());
924
925        lock.lock();
926        c.signalAll();
927        lock.unlock();
928
929        awaitTermination(t1);
930        awaitTermination(t2);
931    }
932
933    /**
934     * await/awaitNanos/awaitUntil is interruptible
935     */
936    public void testInterruptible_await()           { testInterruptible(false, AwaitMethod.await); }
937    public void testInterruptible_await_fair()      { testInterruptible(true,  AwaitMethod.await); }
938    public void testInterruptible_awaitTimed()      { testInterruptible(false, AwaitMethod.awaitTimed); }
939    public void testInterruptible_awaitTimed_fair() { testInterruptible(true,  AwaitMethod.awaitTimed); }
940    public void testInterruptible_awaitNanos()      { testInterruptible(false, AwaitMethod.awaitNanos); }
941    public void testInterruptible_awaitNanos_fair() { testInterruptible(true,  AwaitMethod.awaitNanos); }
942    public void testInterruptible_awaitUntil()      { testInterruptible(false, AwaitMethod.awaitUntil); }
943    public void testInterruptible_awaitUntil_fair() { testInterruptible(true,  AwaitMethod.awaitUntil); }
944    public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
945        final PublicReentrantLock lock =
946            new PublicReentrantLock(fair);
947        final Condition c = lock.newCondition();
948        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
949        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
950            public void realRun() throws InterruptedException {
951                lock.lock();
952                assertLockedByMoi(lock);
953                assertHasNoWaiters(lock, c);
954                pleaseInterrupt.countDown();
955                try {
956                    await(c, awaitMethod);
957                } finally {
958                    assertLockedByMoi(lock);
959                    assertHasNoWaiters(lock, c);
960                    lock.unlock();
961                    assertFalse(Thread.interrupted());
962                }
963            }});
964
965        await(pleaseInterrupt);
966        assertHasWaiters(lock, c, t);
967        t.interrupt();
968        awaitTermination(t);
969        assertNotLocked(lock);
970    }
971
972    /**
973     * signalAll wakes up all threads
974     */
975    public void testSignalAll_await()           { testSignalAll(false, AwaitMethod.await); }
976    public void testSignalAll_await_fair()      { testSignalAll(true,  AwaitMethod.await); }
977    public void testSignalAll_awaitTimed()      { testSignalAll(false, AwaitMethod.awaitTimed); }
978    public void testSignalAll_awaitTimed_fair() { testSignalAll(true,  AwaitMethod.awaitTimed); }
979    public void testSignalAll_awaitNanos()      { testSignalAll(false, AwaitMethod.awaitNanos); }
980    public void testSignalAll_awaitNanos_fair() { testSignalAll(true,  AwaitMethod.awaitNanos); }
981    public void testSignalAll_awaitUntil()      { testSignalAll(false, AwaitMethod.awaitUntil); }
982    public void testSignalAll_awaitUntil_fair() { testSignalAll(true,  AwaitMethod.awaitUntil); }
983    public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
984        final PublicReentrantLock lock = new PublicReentrantLock(fair);
985        final Condition c = lock.newCondition();
986        final CountDownLatch pleaseSignal = new CountDownLatch(2);
987        class Awaiter extends CheckedRunnable {
988            public void realRun() throws InterruptedException {
989                lock.lock();
990                pleaseSignal.countDown();
991                await(c, awaitMethod);
992                lock.unlock();
993            }
994        }
995
996        Thread t1 = newStartedThread(new Awaiter());
997        Thread t2 = newStartedThread(new Awaiter());
998
999        await(pleaseSignal);
1000        lock.lock();
1001        assertHasWaiters(lock, c, t1, t2);
1002        c.signalAll();
1003        assertHasNoWaiters(lock, c);
1004        lock.unlock();
1005        awaitTermination(t1);
1006        awaitTermination(t2);
1007    }
1008
1009    /**
1010     * signal wakes up waiting threads in FIFO order
1011     */
1012    public void testSignalWakesFifo()      { testSignalWakesFifo(false); }
1013    public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
1014    public void testSignalWakesFifo(boolean fair) {
1015        final PublicReentrantLock lock =
1016            new PublicReentrantLock(fair);
1017        final Condition c = lock.newCondition();
1018        final CountDownLatch locked1 = new CountDownLatch(1);
1019        final CountDownLatch locked2 = new CountDownLatch(1);
1020        Thread t1 = newStartedThread(new CheckedRunnable() {
1021            public void realRun() throws InterruptedException {
1022                lock.lock();
1023                locked1.countDown();
1024                c.await();
1025                lock.unlock();
1026            }});
1027
1028        await(locked1);
1029
1030        Thread t2 = newStartedThread(new CheckedRunnable() {
1031            public void realRun() throws InterruptedException {
1032                lock.lock();
1033                locked2.countDown();
1034                c.await();
1035                lock.unlock();
1036            }});
1037
1038        await(locked2);
1039
1040        lock.lock();
1041        assertHasWaiters(lock, c, t1, t2);
1042        assertFalse(lock.hasQueuedThreads());
1043        c.signal();
1044        assertHasWaiters(lock, c, t2);
1045        assertTrue(lock.hasQueuedThread(t1));
1046        assertFalse(lock.hasQueuedThread(t2));
1047        c.signal();
1048        assertHasNoWaiters(lock, c);
1049        assertTrue(lock.hasQueuedThread(t1));
1050        assertTrue(lock.hasQueuedThread(t2));
1051        lock.unlock();
1052        awaitTermination(t1);
1053        awaitTermination(t2);
1054    }
1055
1056    /**
1057     * await after multiple reentrant locking preserves lock count
1058     */
1059    public void testAwaitLockCount()      { testAwaitLockCount(false); }
1060    public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
1061    public void testAwaitLockCount(boolean fair) {
1062        final PublicReentrantLock lock = new PublicReentrantLock(fair);
1063        final Condition c = lock.newCondition();
1064        final CountDownLatch pleaseSignal = new CountDownLatch(2);
1065        Thread t1 = newStartedThread(new CheckedRunnable() {
1066            public void realRun() throws InterruptedException {
1067                lock.lock();
1068                assertLockedByMoi(lock);
1069                assertEquals(1, lock.getHoldCount());
1070                pleaseSignal.countDown();
1071                c.await();
1072                assertLockedByMoi(lock);
1073                assertEquals(1, lock.getHoldCount());
1074                lock.unlock();
1075            }});
1076
1077        Thread t2 = newStartedThread(new CheckedRunnable() {
1078            public void realRun() throws InterruptedException {
1079                lock.lock();
1080                lock.lock();
1081                assertLockedByMoi(lock);
1082                assertEquals(2, lock.getHoldCount());
1083                pleaseSignal.countDown();
1084                c.await();
1085                assertLockedByMoi(lock);
1086                assertEquals(2, lock.getHoldCount());
1087                lock.unlock();
1088                lock.unlock();
1089            }});
1090
1091        await(pleaseSignal);
1092        lock.lock();
1093        assertHasWaiters(lock, c, t1, t2);
1094        assertEquals(1, lock.getHoldCount());
1095        c.signalAll();
1096        assertHasNoWaiters(lock, c);
1097        lock.unlock();
1098        awaitTermination(t1);
1099        awaitTermination(t2);
1100    }
1101
1102    /**
1103     * A serialized lock deserializes as unlocked
1104     */
1105    public void testSerialization()      { testSerialization(false); }
1106    public void testSerialization_fair() { testSerialization(true); }
1107    public void testSerialization(boolean fair) {
1108        ReentrantLock lock = new ReentrantLock(fair);
1109        lock.lock();
1110
1111        ReentrantLock clone = serialClone(lock);
1112        assertEquals(lock.isFair(), clone.isFair());
1113        assertTrue(lock.isLocked());
1114        assertFalse(clone.isLocked());
1115        assertEquals(1, lock.getHoldCount());
1116        assertEquals(0, clone.getHoldCount());
1117        clone.lock();
1118        clone.lock();
1119        assertTrue(clone.isLocked());
1120        assertEquals(2, clone.getHoldCount());
1121        assertEquals(1, lock.getHoldCount());
1122        clone.unlock();
1123        clone.unlock();
1124        assertTrue(lock.isLocked());
1125        assertFalse(clone.isLocked());
1126    }
1127
1128    /**
1129     * toString indicates current lock state
1130     */
1131    public void testToString()      { testToString(false); }
1132    public void testToString_fair() { testToString(true); }
1133    public void testToString(boolean fair) {
1134        ReentrantLock lock = new ReentrantLock(fair);
1135        assertTrue(lock.toString().contains("Unlocked"));
1136        lock.lock();
1137        assertTrue(lock.toString().contains("Locked"));
1138        lock.unlock();
1139        assertTrue(lock.toString().contains("Unlocked"));
1140    }
1141}
1142