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