ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
Revision: 1.12
Committed: Sat Dec 27 19:26:43 2003 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.11: +5 -4 lines
Log Message:
Headers reference Creative Commons

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