ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
Revision: 1.24
Committed: Fri Feb 24 00:03:16 2006 UTC (18 years, 2 months ago) by dl
Branch: MAIN
Changes since 1.23: +1 -0 lines
Log Message:
Make Interruptible locking tests obey delay conventions

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 lock.unlock();
415 t.join();
416 } catch(Exception e){
417 unexpectedException();
418 }
419 }
420
421 /**
422 * lockInterruptibly succeeds when unlocked, else is interruptible
423 */
424 public void testLockInterruptibly2() {
425 final ReentrantLock lock = new ReentrantLock();
426 try {
427 lock.lockInterruptibly();
428 } catch(Exception e) {
429 unexpectedException();
430 }
431 Thread t = new Thread(new InterruptedLockRunnable(lock));
432 try {
433 t.start();
434 t.interrupt();
435 assertTrue(lock.isLocked());
436 assertTrue(lock.isHeldByCurrentThread());
437 t.join();
438 } catch(Exception e){
439 unexpectedException();
440 }
441 }
442
443 /**
444 * Calling await without holding lock throws IllegalMonitorStateException
445 */
446 public void testAwait_IllegalMonitor() {
447 final ReentrantLock lock = new ReentrantLock();
448 final Condition c = lock.newCondition();
449 try {
450 c.await();
451 shouldThrow();
452 }
453 catch (IllegalMonitorStateException success) {
454 }
455 catch (Exception ex) {
456 unexpectedException();
457 }
458 }
459
460 /**
461 * Calling signal without holding lock throws IllegalMonitorStateException
462 */
463 public void testSignal_IllegalMonitor() {
464 final ReentrantLock lock = new ReentrantLock();
465 final Condition c = lock.newCondition();
466 try {
467 c.signal();
468 shouldThrow();
469 }
470 catch (IllegalMonitorStateException success) {
471 }
472 catch (Exception ex) {
473 unexpectedException();
474 }
475 }
476
477 /**
478 * awaitNanos without a signal times out
479 */
480 public void testAwaitNanos_Timeout() {
481 final ReentrantLock lock = new ReentrantLock();
482 final Condition c = lock.newCondition();
483 try {
484 lock.lock();
485 long t = c.awaitNanos(100);
486 assertTrue(t <= 0);
487 lock.unlock();
488 }
489 catch (Exception ex) {
490 unexpectedException();
491 }
492 }
493
494 /**
495 * timed await without a signal times out
496 */
497 public void testAwait_Timeout() {
498 final ReentrantLock lock = new ReentrantLock();
499 final Condition c = lock.newCondition();
500 try {
501 lock.lock();
502 c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);
503 lock.unlock();
504 }
505 catch (Exception ex) {
506 unexpectedException();
507 }
508 }
509
510 /**
511 * awaitUntil without a signal times out
512 */
513 public void testAwaitUntil_Timeout() {
514 final ReentrantLock lock = new ReentrantLock();
515 final Condition c = lock.newCondition();
516 try {
517 lock.lock();
518 java.util.Date d = new java.util.Date();
519 c.awaitUntil(new java.util.Date(d.getTime() + 10));
520 lock.unlock();
521 }
522 catch (Exception ex) {
523 unexpectedException();
524 }
525 }
526
527 /**
528 * await returns when signalled
529 */
530 public void testAwait() {
531 final ReentrantLock lock = new ReentrantLock();
532 final Condition c = lock.newCondition();
533 Thread t = new Thread(new Runnable() {
534 public void run() {
535 try {
536 lock.lock();
537 c.await();
538 lock.unlock();
539 }
540 catch(InterruptedException e) {
541 threadUnexpectedException();
542 }
543 }
544 });
545
546 try {
547 t.start();
548 Thread.sleep(SHORT_DELAY_MS);
549 lock.lock();
550 c.signal();
551 lock.unlock();
552 t.join(SHORT_DELAY_MS);
553 assertFalse(t.isAlive());
554 }
555 catch (Exception ex) {
556 unexpectedException();
557 }
558 }
559
560 /**
561 * hasWaiters throws NPE if null
562 */
563 public void testHasWaitersNPE() {
564 final ReentrantLock lock = new ReentrantLock();
565 try {
566 lock.hasWaiters(null);
567 shouldThrow();
568 } catch (NullPointerException success) {
569 } catch (Exception ex) {
570 unexpectedException();
571 }
572 }
573
574 /**
575 * getWaitQueueLength throws NPE if null
576 */
577 public void testGetWaitQueueLengthNPE() {
578 final ReentrantLock lock = new ReentrantLock();
579 try {
580 lock.getWaitQueueLength(null);
581 shouldThrow();
582 } catch (NullPointerException success) {
583 } catch (Exception ex) {
584 unexpectedException();
585 }
586 }
587
588
589 /**
590 * getWaitingThreads throws NPE if null
591 */
592 public void testGetWaitingThreadsNPE() {
593 final PublicReentrantLock lock = new PublicReentrantLock();
594 try {
595 lock.getWaitingThreads(null);
596 shouldThrow();
597 } catch (NullPointerException success) {
598 } catch (Exception ex) {
599 unexpectedException();
600 }
601 }
602
603
604 /**
605 * hasWaiters throws IAE if not owned
606 */
607 public void testHasWaitersIAE() {
608 final ReentrantLock lock = new ReentrantLock();
609 final Condition c = (lock.newCondition());
610 final ReentrantLock lock2 = new ReentrantLock();
611 try {
612 lock2.hasWaiters(c);
613 shouldThrow();
614 } catch (IllegalArgumentException success) {
615 } catch (Exception ex) {
616 unexpectedException();
617 }
618 }
619
620 /**
621 * hasWaiters throws IMSE if not locked
622 */
623 public void testHasWaitersIMSE() {
624 final ReentrantLock lock = new ReentrantLock();
625 final Condition c = (lock.newCondition());
626 try {
627 lock.hasWaiters(c);
628 shouldThrow();
629 } catch (IllegalMonitorStateException success) {
630 } catch (Exception ex) {
631 unexpectedException();
632 }
633 }
634
635
636 /**
637 * getWaitQueueLength throws IAE if not owned
638 */
639 public void testGetWaitQueueLengthIAE() {
640 final ReentrantLock lock = new ReentrantLock();
641 final Condition c = (lock.newCondition());
642 final ReentrantLock lock2 = new ReentrantLock();
643 try {
644 lock2.getWaitQueueLength(c);
645 shouldThrow();
646 } catch (IllegalArgumentException success) {
647 } catch (Exception ex) {
648 unexpectedException();
649 }
650 }
651
652 /**
653 * getWaitQueueLength throws IMSE if not locked
654 */
655 public void testGetWaitQueueLengthIMSE() {
656 final ReentrantLock lock = new ReentrantLock();
657 final Condition c = (lock.newCondition());
658 try {
659 lock.getWaitQueueLength(c);
660 shouldThrow();
661 } catch (IllegalMonitorStateException success) {
662 } catch (Exception ex) {
663 unexpectedException();
664 }
665 }
666
667
668 /**
669 * getWaitingThreads throws IAE if not owned
670 */
671 public void testGetWaitingThreadsIAE() {
672 final PublicReentrantLock lock = new PublicReentrantLock();
673 final Condition c = (lock.newCondition());
674 final PublicReentrantLock lock2 = new PublicReentrantLock();
675 try {
676 lock2.getWaitingThreads(c);
677 shouldThrow();
678 } catch (IllegalArgumentException success) {
679 } catch (Exception ex) {
680 unexpectedException();
681 }
682 }
683
684 /**
685 * getWaitingThreads throws IMSE if not locked
686 */
687 public void testGetWaitingThreadsIMSE() {
688 final PublicReentrantLock lock = new PublicReentrantLock();
689 final Condition c = (lock.newCondition());
690 try {
691 lock.getWaitingThreads(c);
692 shouldThrow();
693 } catch (IllegalMonitorStateException success) {
694 } catch (Exception ex) {
695 unexpectedException();
696 }
697 }
698
699
700
701 /**
702 * hasWaiters returns true when a thread is waiting, else false
703 */
704 public void testHasWaiters() {
705 final ReentrantLock lock = new ReentrantLock();
706 final Condition c = lock.newCondition();
707 Thread t = new Thread(new Runnable() {
708 public void run() {
709 try {
710 lock.lock();
711 threadAssertFalse(lock.hasWaiters(c));
712 threadAssertEquals(0, lock.getWaitQueueLength(c));
713 c.await();
714 lock.unlock();
715 }
716 catch(InterruptedException e) {
717 threadUnexpectedException();
718 }
719 }
720 });
721
722 try {
723 t.start();
724 Thread.sleep(SHORT_DELAY_MS);
725 lock.lock();
726 assertTrue(lock.hasWaiters(c));
727 assertEquals(1, lock.getWaitQueueLength(c));
728 c.signal();
729 lock.unlock();
730 Thread.sleep(SHORT_DELAY_MS);
731 lock.lock();
732 assertFalse(lock.hasWaiters(c));
733 assertEquals(0, lock.getWaitQueueLength(c));
734 lock.unlock();
735 t.join(SHORT_DELAY_MS);
736 assertFalse(t.isAlive());
737 }
738 catch (Exception ex) {
739 unexpectedException();
740 }
741 }
742
743 /**
744 * getWaitQueueLength returns number of waiting threads
745 */
746 public void testGetWaitQueueLength() {
747 final ReentrantLock lock = new ReentrantLock();
748 final Condition c = lock.newCondition();
749 Thread t1 = new Thread(new Runnable() {
750 public void run() {
751 try {
752 lock.lock();
753 threadAssertFalse(lock.hasWaiters(c));
754 threadAssertEquals(0, lock.getWaitQueueLength(c));
755 c.await();
756 lock.unlock();
757 }
758 catch(InterruptedException e) {
759 threadUnexpectedException();
760 }
761 }
762 });
763
764 Thread t2 = new Thread(new Runnable() {
765 public void run() {
766 try {
767 lock.lock();
768 threadAssertTrue(lock.hasWaiters(c));
769 threadAssertEquals(1, lock.getWaitQueueLength(c));
770 c.await();
771 lock.unlock();
772 }
773 catch(InterruptedException e) {
774 threadUnexpectedException();
775 }
776 }
777 });
778
779 try {
780 t1.start();
781 Thread.sleep(SHORT_DELAY_MS);
782 t2.start();
783 Thread.sleep(SHORT_DELAY_MS);
784 lock.lock();
785 assertTrue(lock.hasWaiters(c));
786 assertEquals(2, lock.getWaitQueueLength(c));
787 c.signalAll();
788 lock.unlock();
789 Thread.sleep(SHORT_DELAY_MS);
790 lock.lock();
791 assertFalse(lock.hasWaiters(c));
792 assertEquals(0, lock.getWaitQueueLength(c));
793 lock.unlock();
794 t1.join(SHORT_DELAY_MS);
795 t2.join(SHORT_DELAY_MS);
796 assertFalse(t1.isAlive());
797 assertFalse(t2.isAlive());
798 }
799 catch (Exception ex) {
800 unexpectedException();
801 }
802 }
803
804 /**
805 * getWaitingThreads returns only and all waiting threads
806 */
807 public void testGetWaitingThreads() {
808 final PublicReentrantLock lock = new PublicReentrantLock();
809 final Condition c = lock.newCondition();
810 Thread t1 = new Thread(new Runnable() {
811 public void run() {
812 try {
813 lock.lock();
814 threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
815 c.await();
816 lock.unlock();
817 }
818 catch(InterruptedException e) {
819 threadUnexpectedException();
820 }
821 }
822 });
823
824 Thread t2 = new Thread(new Runnable() {
825 public void run() {
826 try {
827 lock.lock();
828 threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
829 c.await();
830 lock.unlock();
831 }
832 catch(InterruptedException e) {
833 threadUnexpectedException();
834 }
835 }
836 });
837
838 try {
839 lock.lock();
840 assertTrue(lock.getWaitingThreads(c).isEmpty());
841 lock.unlock();
842 t1.start();
843 Thread.sleep(SHORT_DELAY_MS);
844 t2.start();
845 Thread.sleep(SHORT_DELAY_MS);
846 lock.lock();
847 assertTrue(lock.hasWaiters(c));
848 assertTrue(lock.getWaitingThreads(c).contains(t1));
849 assertTrue(lock.getWaitingThreads(c).contains(t2));
850 c.signalAll();
851 lock.unlock();
852 Thread.sleep(SHORT_DELAY_MS);
853 lock.lock();
854 assertFalse(lock.hasWaiters(c));
855 assertTrue(lock.getWaitingThreads(c).isEmpty());
856 lock.unlock();
857 t1.join(SHORT_DELAY_MS);
858 t2.join(SHORT_DELAY_MS);
859 assertFalse(t1.isAlive());
860 assertFalse(t2.isAlive());
861 }
862 catch (Exception ex) {
863 unexpectedException();
864 }
865 }
866
867 /** A helper class for uninterruptible wait tests */
868 class UninterruptableThread extends Thread {
869 private ReentrantLock lock;
870 private Condition c;
871
872 public volatile boolean canAwake = false;
873 public volatile boolean interrupted = false;
874 public volatile boolean lockStarted = false;
875
876 public UninterruptableThread(ReentrantLock lock, Condition c) {
877 this.lock = lock;
878 this.c = c;
879 }
880
881 public synchronized void run() {
882 lock.lock();
883 lockStarted = true;
884
885 while (!canAwake) {
886 c.awaitUninterruptibly();
887 }
888
889 interrupted = isInterrupted();
890 lock.unlock();
891 }
892 }
893
894 /**
895 * awaitUninterruptibly doesn't abort on interrupt
896 */
897 public void testAwaitUninterruptibly() {
898 final ReentrantLock lock = new ReentrantLock();
899 final Condition c = lock.newCondition();
900 UninterruptableThread thread = new UninterruptableThread(lock, c);
901
902 try {
903 thread.start();
904
905 while (!thread.lockStarted) {
906 Thread.sleep(100);
907 }
908
909 lock.lock();
910 try {
911 thread.interrupt();
912 thread.canAwake = true;
913 c.signal();
914 } finally {
915 lock.unlock();
916 }
917
918 thread.join();
919 assertTrue(thread.interrupted);
920 assertFalse(thread.isAlive());
921 } catch (Exception ex) {
922 unexpectedException();
923 }
924 }
925
926 /**
927 * await is interruptible
928 */
929 public void testAwait_Interrupt() {
930 final ReentrantLock lock = new ReentrantLock();
931 final Condition c = lock.newCondition();
932 Thread t = new Thread(new Runnable() {
933 public void run() {
934 try {
935 lock.lock();
936 c.await();
937 lock.unlock();
938 threadShouldThrow();
939 }
940 catch(InterruptedException success) {
941 }
942 }
943 });
944
945 try {
946 t.start();
947 Thread.sleep(SHORT_DELAY_MS);
948 t.interrupt();
949 t.join(SHORT_DELAY_MS);
950 assertFalse(t.isAlive());
951 }
952 catch (Exception ex) {
953 unexpectedException();
954 }
955 }
956
957 /**
958 * awaitNanos is interruptible
959 */
960 public void testAwaitNanos_Interrupt() {
961 final ReentrantLock lock = new ReentrantLock();
962 final Condition c = lock.newCondition();
963 Thread t = new Thread(new Runnable() {
964 public void run() {
965 try {
966 lock.lock();
967 c.awaitNanos(1000 * 1000 * 1000); // 1 sec
968 lock.unlock();
969 threadShouldThrow();
970 }
971 catch(InterruptedException success) {
972 }
973 }
974 });
975
976 try {
977 t.start();
978 Thread.sleep(SHORT_DELAY_MS);
979 t.interrupt();
980 t.join(SHORT_DELAY_MS);
981 assertFalse(t.isAlive());
982 }
983 catch (Exception ex) {
984 unexpectedException();
985 }
986 }
987
988 /**
989 * awaitUntil is interruptible
990 */
991 public void testAwaitUntil_Interrupt() {
992 final ReentrantLock lock = new ReentrantLock();
993 final Condition c = lock.newCondition();
994 Thread t = new Thread(new Runnable() {
995 public void run() {
996 try {
997 lock.lock();
998 java.util.Date d = new java.util.Date();
999 c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1000 lock.unlock();
1001 threadShouldThrow();
1002 }
1003 catch(InterruptedException success) {
1004 }
1005 }
1006 });
1007
1008 try {
1009 t.start();
1010 Thread.sleep(SHORT_DELAY_MS);
1011 t.interrupt();
1012 t.join(SHORT_DELAY_MS);
1013 assertFalse(t.isAlive());
1014 }
1015 catch (Exception ex) {
1016 unexpectedException();
1017 }
1018 }
1019
1020 /**
1021 * signalAll wakes up all threads
1022 */
1023 public void testSignalAll() {
1024 final ReentrantLock lock = new ReentrantLock();
1025 final Condition c = lock.newCondition();
1026 Thread t1 = new Thread(new Runnable() {
1027 public void run() {
1028 try {
1029 lock.lock();
1030 c.await();
1031 lock.unlock();
1032 }
1033 catch(InterruptedException e) {
1034 threadUnexpectedException();
1035 }
1036 }
1037 });
1038
1039 Thread t2 = new Thread(new Runnable() {
1040 public void run() {
1041 try {
1042 lock.lock();
1043 c.await();
1044 lock.unlock();
1045 }
1046 catch(InterruptedException e) {
1047 threadUnexpectedException();
1048 }
1049 }
1050 });
1051
1052 try {
1053 t1.start();
1054 t2.start();
1055 Thread.sleep(SHORT_DELAY_MS);
1056 lock.lock();
1057 c.signalAll();
1058 lock.unlock();
1059 t1.join(SHORT_DELAY_MS);
1060 t2.join(SHORT_DELAY_MS);
1061 assertFalse(t1.isAlive());
1062 assertFalse(t2.isAlive());
1063 }
1064 catch (Exception ex) {
1065 unexpectedException();
1066 }
1067 }
1068
1069 /**
1070 * await after multiple reentrant locking preserves lock count
1071 */
1072 public void testAwaitLockCount() {
1073 final ReentrantLock lock = new ReentrantLock();
1074 final Condition c = lock.newCondition();
1075 Thread t1 = new Thread(new Runnable() {
1076 public void run() {
1077 try {
1078 lock.lock();
1079 threadAssertEquals(1, lock.getHoldCount());
1080 c.await();
1081 threadAssertEquals(1, lock.getHoldCount());
1082 lock.unlock();
1083 }
1084 catch(InterruptedException e) {
1085 threadUnexpectedException();
1086 }
1087 }
1088 });
1089
1090 Thread t2 = new Thread(new Runnable() {
1091 public void run() {
1092 try {
1093 lock.lock();
1094 lock.lock();
1095 threadAssertEquals(2, lock.getHoldCount());
1096 c.await();
1097 threadAssertEquals(2, lock.getHoldCount());
1098 lock.unlock();
1099 lock.unlock();
1100 }
1101 catch(InterruptedException e) {
1102 threadUnexpectedException();
1103 }
1104 }
1105 });
1106
1107 try {
1108 t1.start();
1109 t2.start();
1110 Thread.sleep(SHORT_DELAY_MS);
1111 lock.lock();
1112 c.signalAll();
1113 lock.unlock();
1114 t1.join(SHORT_DELAY_MS);
1115 t2.join(SHORT_DELAY_MS);
1116 assertFalse(t1.isAlive());
1117 assertFalse(t2.isAlive());
1118 }
1119 catch (Exception ex) {
1120 unexpectedException();
1121 }
1122 }
1123
1124 /**
1125 * A serialized lock deserializes as unlocked
1126 */
1127 public void testSerialization() {
1128 ReentrantLock l = new ReentrantLock();
1129 l.lock();
1130 l.unlock();
1131
1132 try {
1133 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
1134 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
1135 out.writeObject(l);
1136 out.close();
1137
1138 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
1139 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
1140 ReentrantLock r = (ReentrantLock) in.readObject();
1141 r.lock();
1142 r.unlock();
1143 } catch(Exception e){
1144 e.printStackTrace();
1145 unexpectedException();
1146 }
1147 }
1148
1149 /**
1150 * toString indicates current lock state
1151 */
1152 public void testToString() {
1153 ReentrantLock lock = new ReentrantLock();
1154 String us = lock.toString();
1155 assertTrue(us.indexOf("Unlocked") >= 0);
1156 lock.lock();
1157 String ls = lock.toString();
1158 assertTrue(ls.indexOf("Locked") >= 0);
1159 }
1160
1161 }