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