ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
Revision: 1.26
Committed: Mon Nov 2 20:28:31 2009 UTC (14 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.25: +70 -70 lines
Log Message:
whitespace

File Contents

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