ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
Revision: 1.11
Committed: Sat Dec 27 18:27:02 2003 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.10: +3 -76 lines
Log Message:
Adjust protected method tests

File Contents

# Content
1 /*
2 * Written by members of JCP JSR-166 Expert Group and released to the
3 * public domain. Use, modify, and redistribute this code in any way
4 * without acknowledgement. Other contributors include Andrew Wright,
5 * Jeffrey Hayes, Pat Fischer, Mike Judd.
6 */
7
8 import junit.framework.*;
9 import java.util.concurrent.locks.*;
10 import java.util.concurrent.*;
11 import java.util.*;
12 import java.io.*;
13
14 public class ReentrantLockTest extends JSR166TestCase {
15 public static void main(String[] args) {
16 junit.textui.TestRunner.run (suite());
17 }
18 public static Test suite() {
19 return new TestSuite(ReentrantLockTest.class);
20 }
21
22 /**
23 * A runnable calling lockInterruptibly
24 */
25 class InterruptibleLockRunnable implements Runnable {
26 final ReentrantLock lock;
27 InterruptibleLockRunnable(ReentrantLock l) { lock = l; }
28 public void run() {
29 try {
30 lock.lockInterruptibly();
31 } catch(InterruptedException success){}
32 }
33 }
34
35
36 /**
37 * A runnable calling lockInterruptibly that expects to be
38 * interrupted
39 */
40 class InterruptedLockRunnable implements Runnable {
41 final ReentrantLock lock;
42 InterruptedLockRunnable(ReentrantLock l) { lock = l; }
43 public void run() {
44 try {
45 lock.lockInterruptibly();
46 threadShouldThrow();
47 } catch(InterruptedException success){}
48 }
49 }
50
51 /**
52 * Subclass to expose protected methods
53 */
54 static class PublicReentrantLock extends ReentrantLock {
55 PublicReentrantLock() { super(); }
56 public Collection<Thread> getQueuedThreads() {
57 return super.getQueuedThreads();
58 }
59
60 }
61
62 /**
63 * Constructor sets given fairness
64 */
65 public void testConstructor() {
66 ReentrantLock rl = new ReentrantLock();
67 assertFalse(rl.isFair());
68 ReentrantLock r2 = new ReentrantLock(true);
69 assertTrue(r2.isFair());
70 }
71
72 /**
73 * locking an unlocked lock succeeds
74 */
75 public void testLock() {
76 ReentrantLock rl = new ReentrantLock();
77 rl.lock();
78 assertTrue(rl.isLocked());
79 rl.unlock();
80 }
81
82 /**
83 * locking an unlocked fair lock succeeds
84 */
85 public void testFairLock() {
86 ReentrantLock rl = new ReentrantLock(true);
87 rl.lock();
88 assertTrue(rl.isLocked());
89 rl.unlock();
90 }
91
92 /**
93 * Unlocking an unlocked lock throws IllegalMonitorStateException
94 */
95 public void testUnlock_IllegalMonitorStateException() {
96 ReentrantLock rl = new ReentrantLock();
97 try {
98 rl.unlock();
99 shouldThrow();
100
101 } catch(IllegalMonitorStateException success){}
102 }
103
104 /**
105 * trylock on an unlocked lock succeeds
106 */
107 public void testTryLock() {
108 ReentrantLock rl = new ReentrantLock();
109 assertTrue(rl.tryLock());
110 assertTrue(rl.isLocked());
111 rl.unlock();
112 }
113
114
115 /**
116 * getQueueLength reports number of waiting threads
117 */
118 public void testGetQueueLength() {
119 final ReentrantLock lock = new ReentrantLock();
120 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
121 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
122 try {
123 assertEquals(0, lock.getQueueLength());
124 lock.lock();
125 t1.start();
126 Thread.sleep(SHORT_DELAY_MS);
127 assertEquals(1, lock.getQueueLength());
128 t2.start();
129 Thread.sleep(SHORT_DELAY_MS);
130 assertEquals(2, lock.getQueueLength());
131 t1.interrupt();
132 Thread.sleep(SHORT_DELAY_MS);
133 assertEquals(1, lock.getQueueLength());
134 lock.unlock();
135 Thread.sleep(SHORT_DELAY_MS);
136 assertEquals(0, lock.getQueueLength());
137 t1.join();
138 t2.join();
139 } catch(Exception e){
140 unexpectedException();
141 }
142 }
143
144 /**
145 * getQueuedThreads includes waiting threads
146 */
147 public void testGetQueuedThreads() {
148 final PublicReentrantLock lock = new PublicReentrantLock();
149 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
150 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
151 try {
152 assertTrue(lock.getQueuedThreads().isEmpty());
153 lock.lock();
154 assertTrue(lock.getQueuedThreads().isEmpty());
155 t1.start();
156 Thread.sleep(SHORT_DELAY_MS);
157 assertTrue(lock.getQueuedThreads().contains(t1));
158 t2.start();
159 Thread.sleep(SHORT_DELAY_MS);
160 assertTrue(lock.getQueuedThreads().contains(t1));
161 assertTrue(lock.getQueuedThreads().contains(t2));
162 t1.interrupt();
163 Thread.sleep(SHORT_DELAY_MS);
164 assertFalse(lock.getQueuedThreads().contains(t1));
165 assertTrue(lock.getQueuedThreads().contains(t2));
166 lock.unlock();
167 Thread.sleep(SHORT_DELAY_MS);
168 assertTrue(lock.getQueuedThreads().isEmpty());
169 t1.join();
170 t2.join();
171 } catch(Exception e){
172 unexpectedException();
173 }
174 }
175
176
177 /**
178 * timed trylock is interruptible.
179 */
180 public void testInterruptedException2() {
181 final ReentrantLock lock = new ReentrantLock();
182 lock.lock();
183 Thread t = new Thread(new Runnable() {
184 public void run() {
185 try {
186 lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS);
187 threadShouldThrow();
188 } catch(InterruptedException success){}
189 }
190 });
191 try {
192 t.start();
193 t.interrupt();
194 } catch(Exception e){
195 unexpectedException();
196 }
197 }
198
199
200 /**
201 * Trylock on a locked lock fails
202 */
203 public void testTryLockWhenLocked() {
204 final ReentrantLock lock = new ReentrantLock();
205 lock.lock();
206 Thread t = new Thread(new Runnable() {
207 public void run() {
208 threadAssertFalse(lock.tryLock());
209 }
210 });
211 try {
212 t.start();
213 t.join();
214 lock.unlock();
215 } catch(Exception e){
216 unexpectedException();
217 }
218 }
219
220 /**
221 * Timed trylock on a locked lock times out
222 */
223 public void testTryLock_Timeout() {
224 final ReentrantLock lock = new ReentrantLock();
225 lock.lock();
226 Thread t = new Thread(new Runnable() {
227 public void run() {
228 try {
229 threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS));
230 } catch (Exception ex) {
231 threadUnexpectedException();
232 }
233 }
234 });
235 try {
236 t.start();
237 t.join();
238 lock.unlock();
239 } catch(Exception e){
240 unexpectedException();
241 }
242 }
243
244 /**
245 * getHoldCount returns number of recursive holds
246 */
247 public void testGetHoldCount() {
248 ReentrantLock lock = new ReentrantLock();
249 for(int i = 1; i <= SIZE; i++) {
250 lock.lock();
251 assertEquals(i,lock.getHoldCount());
252 }
253 for(int i = SIZE; i > 0; i--) {
254 lock.unlock();
255 assertEquals(i-1,lock.getHoldCount());
256 }
257 }
258
259
260 /**
261 * isLocked is true when locked and false when not
262 */
263 public void testIsLocked() {
264 final ReentrantLock lock = new ReentrantLock();
265 lock.lock();
266 assertTrue(lock.isLocked());
267 lock.unlock();
268 assertFalse(lock.isLocked());
269 Thread t = new Thread(new Runnable() {
270 public void run() {
271 lock.lock();
272 try {
273 Thread.sleep(SMALL_DELAY_MS);
274 }
275 catch(Exception e) {
276 threadUnexpectedException();
277 }
278 lock.unlock();
279 }
280 });
281 try {
282 t.start();
283 Thread.sleep(SHORT_DELAY_MS);
284 assertTrue(lock.isLocked());
285 t.join();
286 assertFalse(lock.isLocked());
287 } catch(Exception e){
288 unexpectedException();
289 }
290 }
291
292
293 /**
294 * lockInterruptibly is interruptible.
295 */
296 public void testLockInterruptibly1() {
297 final ReentrantLock lock = new ReentrantLock();
298 lock.lock();
299 Thread t = new Thread(new InterruptedLockRunnable(lock));
300 try {
301 t.start();
302 t.interrupt();
303 lock.unlock();
304 t.join();
305 } catch(Exception e){
306 unexpectedException();
307 }
308 }
309
310 /**
311 * lockInterruptibly succeeds when unlocked, else is interruptible
312 */
313 public void testLockInterruptibly2() {
314 final ReentrantLock lock = new ReentrantLock();
315 try {
316 lock.lockInterruptibly();
317 } catch(Exception e) {
318 unexpectedException();
319 }
320 Thread t = new Thread(new InterruptedLockRunnable(lock));
321 try {
322 t.start();
323 t.interrupt();
324 assertTrue(lock.isLocked());
325 assertTrue(lock.isHeldByCurrentThread());
326 t.join();
327 } catch(Exception e){
328 unexpectedException();
329 }
330 }
331
332 /**
333 * Calling await without holding lock throws IllegalMonitorStateException
334 */
335 public void testAwait_IllegalMonitor() {
336 final ReentrantLock lock = new ReentrantLock();
337 final Condition c = lock.newCondition();
338 try {
339 c.await();
340 shouldThrow();
341 }
342 catch (IllegalMonitorStateException success) {
343 }
344 catch (Exception ex) {
345 unexpectedException();
346 }
347 }
348
349 /**
350 * Calling signal without holding lock throws IllegalMonitorStateException
351 */
352 public void testSignal_IllegalMonitor() {
353 final ReentrantLock lock = new ReentrantLock();
354 final Condition c = lock.newCondition();
355 try {
356 c.signal();
357 shouldThrow();
358 }
359 catch (IllegalMonitorStateException success) {
360 }
361 catch (Exception ex) {
362 unexpectedException();
363 }
364 }
365
366 /**
367 * awaitNanos without a signal times out
368 */
369 public void testAwaitNanos_Timeout() {
370 final ReentrantLock lock = new ReentrantLock();
371 final Condition c = lock.newCondition();
372 try {
373 lock.lock();
374 long t = c.awaitNanos(100);
375 assertTrue(t <= 0);
376 lock.unlock();
377 }
378 catch (Exception ex) {
379 unexpectedException();
380 }
381 }
382
383 /**
384 * timed await without a signal times out
385 */
386 public void testAwait_Timeout() {
387 final ReentrantLock lock = new ReentrantLock();
388 final Condition c = lock.newCondition();
389 try {
390 lock.lock();
391 assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
392 lock.unlock();
393 }
394 catch (Exception ex) {
395 unexpectedException();
396 }
397 }
398
399 /**
400 * awaitUntil without a signal times out
401 */
402 public void testAwaitUntil_Timeout() {
403 final ReentrantLock lock = new ReentrantLock();
404 final Condition c = lock.newCondition();
405 try {
406 lock.lock();
407 java.util.Date d = new java.util.Date();
408 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
409 lock.unlock();
410 }
411 catch (Exception ex) {
412 unexpectedException();
413 }
414 }
415
416 /**
417 * await returns when signalled
418 */
419 public void testAwait() {
420 final ReentrantLock lock = new ReentrantLock();
421 final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
422 Thread t = new Thread(new Runnable() {
423 public void run() {
424 try {
425 lock.lock();
426 c.await();
427 lock.unlock();
428 }
429 catch(InterruptedException e) {
430 threadUnexpectedException();
431 }
432 }
433 });
434
435 try {
436 t.start();
437 Thread.sleep(SHORT_DELAY_MS);
438 lock.lock();
439 c.signal();
440 lock.unlock();
441 t.join(SHORT_DELAY_MS);
442 assertFalse(t.isAlive());
443 }
444 catch (Exception ex) {
445 unexpectedException();
446 }
447 }
448
449 /**
450 * hasWaiters returns true when a thread is waiting, else false
451 */
452 public void testHasWaiters() {
453 final ReentrantLock lock = new ReentrantLock();
454 final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
455 Thread t = new Thread(new Runnable() {
456 public void run() {
457 try {
458 lock.lock();
459 threadAssertFalse(c.hasWaiters());
460 threadAssertEquals(0, c.getWaitQueueLength());
461 c.await();
462 lock.unlock();
463 }
464 catch(InterruptedException e) {
465 threadUnexpectedException();
466 }
467 }
468 });
469
470 try {
471 t.start();
472 Thread.sleep(SHORT_DELAY_MS);
473 lock.lock();
474 assertTrue(c.hasWaiters());
475 assertEquals(1, c.getWaitQueueLength());
476 c.signal();
477 lock.unlock();
478 Thread.sleep(SHORT_DELAY_MS);
479 lock.lock();
480 assertFalse(c.hasWaiters());
481 assertEquals(0, c.getWaitQueueLength());
482 lock.unlock();
483 t.join(SHORT_DELAY_MS);
484 assertFalse(t.isAlive());
485 }
486 catch (Exception ex) {
487 unexpectedException();
488 }
489 }
490
491 /**
492 * getWaitQueueLength returns number of waiting threads
493 */
494 public void testGetWaitQueueLength() {
495 final ReentrantLock lock = new ReentrantLock();
496 final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
497 Thread t1 = new Thread(new Runnable() {
498 public void run() {
499 try {
500 lock.lock();
501 threadAssertFalse(c.hasWaiters());
502 threadAssertEquals(0, c.getWaitQueueLength());
503 c.await();
504 lock.unlock();
505 }
506 catch(InterruptedException e) {
507 threadUnexpectedException();
508 }
509 }
510 });
511
512 Thread t2 = new Thread(new Runnable() {
513 public void run() {
514 try {
515 lock.lock();
516 threadAssertTrue(c.hasWaiters());
517 threadAssertEquals(1, c.getWaitQueueLength());
518 c.await();
519 lock.unlock();
520 }
521 catch(InterruptedException e) {
522 threadUnexpectedException();
523 }
524 }
525 });
526
527 try {
528 t1.start();
529 Thread.sleep(SHORT_DELAY_MS);
530 t2.start();
531 Thread.sleep(SHORT_DELAY_MS);
532 lock.lock();
533 assertTrue(c.hasWaiters());
534 assertEquals(2, c.getWaitQueueLength());
535 c.signalAll();
536 lock.unlock();
537 Thread.sleep(SHORT_DELAY_MS);
538 lock.lock();
539 assertFalse(c.hasWaiters());
540 assertEquals(0, c.getWaitQueueLength());
541 lock.unlock();
542 t1.join(SHORT_DELAY_MS);
543 t2.join(SHORT_DELAY_MS);
544 assertFalse(t1.isAlive());
545 assertFalse(t2.isAlive());
546 }
547 catch (Exception ex) {
548 unexpectedException();
549 }
550 }
551
552 /**
553 * awaitUninterruptibly doesn't abort on interrupt
554 */
555 public void testAwaitUninterruptibly() {
556 final ReentrantLock lock = new ReentrantLock();
557 final Condition c = lock.newCondition();
558 Thread t = new Thread(new Runnable() {
559 public void run() {
560 lock.lock();
561 c.awaitUninterruptibly();
562 lock.unlock();
563 }
564 });
565
566 try {
567 t.start();
568 Thread.sleep(SHORT_DELAY_MS);
569 t.interrupt();
570 lock.lock();
571 c.signal();
572 lock.unlock();
573 assert(t.isInterrupted());
574 t.join(SHORT_DELAY_MS);
575 assertFalse(t.isAlive());
576 }
577 catch (Exception ex) {
578 unexpectedException();
579 }
580 }
581
582 /**
583 * await is interruptible
584 */
585 public void testAwait_Interrupt() {
586 final ReentrantLock lock = new ReentrantLock();
587 final Condition c = lock.newCondition();
588 Thread t = new Thread(new Runnable() {
589 public void run() {
590 try {
591 lock.lock();
592 c.await();
593 lock.unlock();
594 threadShouldThrow();
595 }
596 catch(InterruptedException success) {
597 }
598 }
599 });
600
601 try {
602 t.start();
603 Thread.sleep(SHORT_DELAY_MS);
604 t.interrupt();
605 t.join(SHORT_DELAY_MS);
606 assertFalse(t.isAlive());
607 }
608 catch (Exception ex) {
609 unexpectedException();
610 }
611 }
612
613 /**
614 * awaitNanos is interruptible
615 */
616 public void testAwaitNanos_Interrupt() {
617 final ReentrantLock lock = new ReentrantLock();
618 final Condition c = lock.newCondition();
619 Thread t = new Thread(new Runnable() {
620 public void run() {
621 try {
622 lock.lock();
623 c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
624 lock.unlock();
625 threadShouldThrow();
626 }
627 catch(InterruptedException success) {
628 }
629 }
630 });
631
632 try {
633 t.start();
634 Thread.sleep(SHORT_DELAY_MS);
635 t.interrupt();
636 t.join(SHORT_DELAY_MS);
637 assertFalse(t.isAlive());
638 }
639 catch (Exception ex) {
640 unexpectedException();
641 }
642 }
643
644 /**
645 * awaitUntil is interruptible
646 */
647 public void testAwaitUntil_Interrupt() {
648 final ReentrantLock lock = new ReentrantLock();
649 final Condition c = lock.newCondition();
650 Thread t = new Thread(new Runnable() {
651 public void run() {
652 try {
653 lock.lock();
654 java.util.Date d = new java.util.Date();
655 c.awaitUntil(new java.util.Date(d.getTime() + 10000));
656 lock.unlock();
657 threadShouldThrow();
658 }
659 catch(InterruptedException success) {
660 }
661 }
662 });
663
664 try {
665 t.start();
666 Thread.sleep(SHORT_DELAY_MS);
667 t.interrupt();
668 t.join(SHORT_DELAY_MS);
669 assertFalse(t.isAlive());
670 }
671 catch (Exception ex) {
672 unexpectedException();
673 }
674 }
675
676 /**
677 * signalAll wakes up all threads
678 */
679 public void testSignalAll() {
680 final ReentrantLock lock = new ReentrantLock();
681 final Condition c = lock.newCondition();
682 Thread t1 = new Thread(new Runnable() {
683 public void run() {
684 try {
685 lock.lock();
686 c.await();
687 lock.unlock();
688 }
689 catch(InterruptedException e) {
690 threadUnexpectedException();
691 }
692 }
693 });
694
695 Thread t2 = new Thread(new Runnable() {
696 public void run() {
697 try {
698 lock.lock();
699 c.await();
700 lock.unlock();
701 }
702 catch(InterruptedException e) {
703 threadUnexpectedException();
704 }
705 }
706 });
707
708 try {
709 t1.start();
710 t2.start();
711 Thread.sleep(SHORT_DELAY_MS);
712 lock.lock();
713 c.signalAll();
714 lock.unlock();
715 t1.join(SHORT_DELAY_MS);
716 t2.join(SHORT_DELAY_MS);
717 assertFalse(t1.isAlive());
718 assertFalse(t2.isAlive());
719 }
720 catch (Exception ex) {
721 unexpectedException();
722 }
723 }
724
725 /**
726 * A serialized lock deserializes as unlocked
727 */
728 public void testSerialization() {
729 ReentrantLock l = new ReentrantLock();
730 l.lock();
731 l.unlock();
732
733 try {
734 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
735 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
736 out.writeObject(l);
737 out.close();
738
739 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
740 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
741 ReentrantLock r = (ReentrantLock) in.readObject();
742 r.lock();
743 r.unlock();
744 } catch(Exception e){
745 e.printStackTrace();
746 unexpectedException();
747 }
748 }
749
750 }