ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.45
Committed: Sun May 1 23:49:41 2011 UTC (13 years ago) by jsr166
Branch: MAIN
Changes since 1.44: +40 -81 lines
Log Message:
use newStartedThread

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