ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.51
Committed: Mon May 2 00:14:09 2011 UTC (13 years ago) by jsr166
Branch: MAIN
Changes since 1.50: +1 -1 lines
Log Message:
Improve testReadLockInterruptibly

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