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

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 Thread.sleep(SHORT_DELAY_MS);
686 t.join();
687 lock.writeLock().unlock();
688 }
689
690 /**
691 * read lockInterruptibly succeeds if lock free else is interruptible
692 */
693 public void testReadLockInterruptibly() throws InterruptedException {
694 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
695 lock.writeLock().lockInterruptibly();
696 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
697 public void realRun() throws InterruptedException {
698 lock.readLock().lockInterruptibly();
699 }});
700
701 Thread.sleep(SHORT_DELAY_MS);
702 t.interrupt();
703 t.join();
704 lock.writeLock().unlock();
705 }
706
707 /**
708 * Calling await without holding lock throws IllegalMonitorStateException
709 */
710 public void testAwait_IllegalMonitor() throws InterruptedException {
711 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
712 final Condition c = lock.writeLock().newCondition();
713 try {
714 c.await();
715 shouldThrow();
716 } catch (IllegalMonitorStateException success) {}
717 }
718
719 /**
720 * Calling signal without holding lock throws IllegalMonitorStateException
721 */
722 public void testSignal_IllegalMonitor() {
723 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
724 final Condition c = lock.writeLock().newCondition();
725 try {
726 c.signal();
727 shouldThrow();
728 } catch (IllegalMonitorStateException success) {}
729 }
730
731 /**
732 * awaitNanos without a signal times out
733 */
734 public void testAwaitNanos_Timeout() throws InterruptedException {
735 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
736 final Condition c = lock.writeLock().newCondition();
737
738 lock.writeLock().lock();
739 long t = c.awaitNanos(100);
740 assertTrue(t <= 0);
741 lock.writeLock().unlock();
742 }
743
744
745 /**
746 * timed await without a signal times out
747 */
748 public void testAwait_Timeout() throws InterruptedException {
749 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
750 final Condition c = lock.writeLock().newCondition();
751 lock.writeLock().lock();
752 assertFalse(c.await(SHORT_DELAY_MS, MILLISECONDS));
753 lock.writeLock().unlock();
754 }
755
756 /**
757 * awaitUntil without a signal times out
758 */
759 public void testAwaitUntil_Timeout() throws InterruptedException {
760 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
761 final Condition c = lock.writeLock().newCondition();
762 lock.writeLock().lock();
763 java.util.Date d = new java.util.Date();
764 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
765 lock.writeLock().unlock();
766 }
767
768 /**
769 * await returns when signalled
770 */
771 public void testAwait() throws InterruptedException {
772 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
773 final Condition c = lock.writeLock().newCondition();
774 Thread t = newStartedThread(new CheckedRunnable() {
775 public void realRun() throws InterruptedException {
776 lock.writeLock().lock();
777 c.await();
778 lock.writeLock().unlock();
779 }});
780
781 Thread.sleep(SHORT_DELAY_MS);
782 lock.writeLock().lock();
783 c.signal();
784 lock.writeLock().unlock();
785 t.join(SHORT_DELAY_MS);
786 assertFalse(t.isAlive());
787 }
788
789 /** A helper class for uninterruptible wait tests */
790 class UninterruptableThread extends Thread {
791 private Lock lock;
792 private Condition c;
793
794 public volatile boolean canAwake = false;
795 public volatile boolean interrupted = false;
796 public volatile boolean lockStarted = false;
797
798 public UninterruptableThread(Lock lock, Condition c) {
799 this.lock = lock;
800 this.c = c;
801 }
802
803 public synchronized void run() {
804 lock.lock();
805 lockStarted = true;
806
807 while (!canAwake) {
808 c.awaitUninterruptibly();
809 }
810
811 interrupted = isInterrupted();
812 lock.unlock();
813 }
814 }
815
816 /**
817 * awaitUninterruptibly doesn't abort on interrupt
818 */
819 public void testAwaitUninterruptibly() throws InterruptedException {
820 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
821 final Condition c = lock.writeLock().newCondition();
822 UninterruptableThread thread = new UninterruptableThread(lock.writeLock(), c);
823
824 thread.start();
825
826 while (!thread.lockStarted) {
827 Thread.sleep(100);
828 }
829
830 lock.writeLock().lock();
831 try {
832 thread.interrupt();
833 thread.canAwake = true;
834 c.signal();
835 } finally {
836 lock.writeLock().unlock();
837 }
838
839 thread.join();
840 assertTrue(thread.interrupted);
841 assertFalse(thread.isAlive());
842 }
843
844 /**
845 * await is interruptible
846 */
847 public void testAwait_Interrupt() throws InterruptedException {
848 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
849 final Condition c = lock.writeLock().newCondition();
850 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
851 public void realRun() throws InterruptedException {
852 lock.writeLock().lock();
853 c.await();
854 lock.writeLock().unlock();
855 }});
856
857 Thread.sleep(SHORT_DELAY_MS);
858 t.interrupt();
859 t.join(SHORT_DELAY_MS);
860 assertFalse(t.isAlive());
861 }
862
863 /**
864 * awaitNanos is interruptible
865 */
866 public void testAwaitNanos_Interrupt() throws InterruptedException {
867 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
868 final Condition c = lock.writeLock().newCondition();
869 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
870 public void realRun() throws InterruptedException {
871 lock.writeLock().lock();
872 c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS));
873 lock.writeLock().unlock();
874 }});
875
876 Thread.sleep(SHORT_DELAY_MS);
877 t.interrupt();
878 t.join(SHORT_DELAY_MS);
879 assertFalse(t.isAlive());
880 }
881
882 /**
883 * awaitUntil is interruptible
884 */
885 public void testAwaitUntil_Interrupt() throws InterruptedException {
886 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
887 final Condition c = lock.writeLock().newCondition();
888 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
889 public void realRun() throws InterruptedException {
890 lock.writeLock().lock();
891 java.util.Date d = new java.util.Date();
892 c.awaitUntil(new java.util.Date(d.getTime() + 10000));
893 lock.writeLock().unlock();
894 }});
895
896 Thread.sleep(SHORT_DELAY_MS);
897 t.interrupt();
898 t.join(SHORT_DELAY_MS);
899 assertFalse(t.isAlive());
900 }
901
902 /**
903 * signalAll wakes up all threads
904 */
905 public void testSignalAll() throws InterruptedException {
906 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
907 final Condition c = lock.writeLock().newCondition();
908 Thread t1 = newStartedThread(new CheckedRunnable() {
909 public void realRun() throws InterruptedException {
910 lock.writeLock().lock();
911 c.await();
912 lock.writeLock().unlock();
913 }});
914
915 Thread t2 = newStartedThread(new CheckedRunnable() {
916 public void realRun() throws InterruptedException {
917 lock.writeLock().lock();
918 c.await();
919 lock.writeLock().unlock();
920 }});
921
922 Thread.sleep(SHORT_DELAY_MS);
923 lock.writeLock().lock();
924 c.signalAll();
925 lock.writeLock().unlock();
926 t1.join(SHORT_DELAY_MS);
927 t2.join(SHORT_DELAY_MS);
928 assertFalse(t1.isAlive());
929 assertFalse(t2.isAlive());
930 }
931
932 /**
933 * A serialized lock deserializes as unlocked
934 */
935 public void testSerialization() throws Exception {
936 ReentrantReadWriteLock l = new ReentrantReadWriteLock();
937 l.readLock().lock();
938 l.readLock().unlock();
939
940 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
941 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
942 out.writeObject(l);
943 out.close();
944
945 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
946 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
947 ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
948 r.readLock().lock();
949 r.readLock().unlock();
950 }
951
952 /**
953 * hasQueuedThreads reports whether there are waiting threads
954 */
955 public void testhasQueuedThreads() throws InterruptedException {
956 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
957 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
958 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
959 assertFalse(lock.hasQueuedThreads());
960 lock.writeLock().lock();
961 t1.start();
962 Thread.sleep(SHORT_DELAY_MS);
963 assertTrue(lock.hasQueuedThreads());
964 t2.start();
965 Thread.sleep(SHORT_DELAY_MS);
966 assertTrue(lock.hasQueuedThreads());
967 t1.interrupt();
968 Thread.sleep(SHORT_DELAY_MS);
969 assertTrue(lock.hasQueuedThreads());
970 lock.writeLock().unlock();
971 Thread.sleep(SHORT_DELAY_MS);
972 assertFalse(lock.hasQueuedThreads());
973 t1.join();
974 t2.join();
975 }
976
977 /**
978 * hasQueuedThread(null) throws NPE
979 */
980 public void testHasQueuedThreadNPE() {
981 final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
982 try {
983 sync.hasQueuedThread(null);
984 shouldThrow();
985 } catch (NullPointerException success) {}
986 }
987
988 /**
989 * hasQueuedThread reports whether a thread is queued.
990 */
991 public void testHasQueuedThread() throws InterruptedException {
992 final ReentrantReadWriteLock sync = new ReentrantReadWriteLock();
993 Thread t1 = new Thread(new InterruptedLockRunnable(sync));
994 Thread t2 = new Thread(new InterruptibleLockRunnable(sync));
995 assertFalse(sync.hasQueuedThread(t1));
996 assertFalse(sync.hasQueuedThread(t2));
997 sync.writeLock().lock();
998 t1.start();
999 Thread.sleep(SHORT_DELAY_MS);
1000 assertTrue(sync.hasQueuedThread(t1));
1001 t2.start();
1002 Thread.sleep(SHORT_DELAY_MS);
1003 assertTrue(sync.hasQueuedThread(t1));
1004 assertTrue(sync.hasQueuedThread(t2));
1005 t1.interrupt();
1006 Thread.sleep(SHORT_DELAY_MS);
1007 assertFalse(sync.hasQueuedThread(t1));
1008 assertTrue(sync.hasQueuedThread(t2));
1009 sync.writeLock().unlock();
1010 Thread.sleep(SHORT_DELAY_MS);
1011 assertFalse(sync.hasQueuedThread(t1));
1012 Thread.sleep(SHORT_DELAY_MS);
1013 assertFalse(sync.hasQueuedThread(t2));
1014 t1.join();
1015 t2.join();
1016 }
1017
1018
1019 /**
1020 * getQueueLength reports number of waiting threads
1021 */
1022 public void testGetQueueLength() throws InterruptedException {
1023 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1024 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1025 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1026 assertEquals(0, lock.getQueueLength());
1027 lock.writeLock().lock();
1028 t1.start();
1029 Thread.sleep(SHORT_DELAY_MS);
1030 assertEquals(1, lock.getQueueLength());
1031 t2.start();
1032 Thread.sleep(SHORT_DELAY_MS);
1033 assertEquals(2, lock.getQueueLength());
1034 t1.interrupt();
1035 Thread.sleep(SHORT_DELAY_MS);
1036 assertEquals(1, lock.getQueueLength());
1037 lock.writeLock().unlock();
1038 Thread.sleep(SHORT_DELAY_MS);
1039 assertEquals(0, lock.getQueueLength());
1040 t1.join();
1041 t2.join();
1042 }
1043
1044 /**
1045 * getQueuedThreads includes waiting threads
1046 */
1047 public void testGetQueuedThreads() throws InterruptedException {
1048 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1049 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1050 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1051 assertTrue(lock.getQueuedThreads().isEmpty());
1052 lock.writeLock().lock();
1053 assertTrue(lock.getQueuedThreads().isEmpty());
1054 t1.start();
1055 Thread.sleep(SHORT_DELAY_MS);
1056 assertTrue(lock.getQueuedThreads().contains(t1));
1057 t2.start();
1058 Thread.sleep(SHORT_DELAY_MS);
1059 assertTrue(lock.getQueuedThreads().contains(t1));
1060 assertTrue(lock.getQueuedThreads().contains(t2));
1061 t1.interrupt();
1062 Thread.sleep(SHORT_DELAY_MS);
1063 assertFalse(lock.getQueuedThreads().contains(t1));
1064 assertTrue(lock.getQueuedThreads().contains(t2));
1065 lock.writeLock().unlock();
1066 Thread.sleep(SHORT_DELAY_MS);
1067 assertTrue(lock.getQueuedThreads().isEmpty());
1068 t1.join();
1069 t2.join();
1070 }
1071
1072 /**
1073 * hasWaiters throws NPE if null
1074 */
1075 public void testHasWaitersNPE() {
1076 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1077 try {
1078 lock.hasWaiters(null);
1079 shouldThrow();
1080 } catch (NullPointerException success) {}
1081 }
1082
1083 /**
1084 * getWaitQueueLength throws NPE if null
1085 */
1086 public void testGetWaitQueueLengthNPE() {
1087 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1088 try {
1089 lock.getWaitQueueLength(null);
1090 shouldThrow();
1091 } catch (NullPointerException success) {}
1092 }
1093
1094
1095 /**
1096 * getWaitingThreads throws NPE if null
1097 */
1098 public void testGetWaitingThreadsNPE() {
1099 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1100 try {
1101 lock.getWaitingThreads(null);
1102 shouldThrow();
1103 } catch (NullPointerException success) {}
1104 }
1105
1106 /**
1107 * hasWaiters throws IAE if not owned
1108 */
1109 public void testHasWaitersIAE() {
1110 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1111 final Condition c = lock.writeLock().newCondition();
1112 final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1113 try {
1114 lock2.hasWaiters(c);
1115 shouldThrow();
1116 } catch (IllegalArgumentException success) {}
1117 }
1118
1119 /**
1120 * hasWaiters throws IMSE if not locked
1121 */
1122 public void testHasWaitersIMSE() {
1123 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1124 final Condition c = lock.writeLock().newCondition();
1125 try {
1126 lock.hasWaiters(c);
1127 shouldThrow();
1128 } catch (IllegalMonitorStateException success) {}
1129 }
1130
1131
1132 /**
1133 * getWaitQueueLength throws IAE if not owned
1134 */
1135 public void testGetWaitQueueLengthIAE() {
1136 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1137 final Condition c = lock.writeLock().newCondition();
1138 final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1139 try {
1140 lock2.getWaitQueueLength(c);
1141 shouldThrow();
1142 } catch (IllegalArgumentException success) {}
1143 }
1144
1145 /**
1146 * getWaitQueueLength throws IMSE if not locked
1147 */
1148 public void testGetWaitQueueLengthIMSE() {
1149 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1150 final Condition c = lock.writeLock().newCondition();
1151 try {
1152 lock.getWaitQueueLength(c);
1153 shouldThrow();
1154 } catch (IllegalMonitorStateException success) {}
1155 }
1156
1157
1158 /**
1159 * getWaitingThreads throws IAE if not owned
1160 */
1161 public void testGetWaitingThreadsIAE() {
1162 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1163 final Condition c = lock.writeLock().newCondition();
1164 final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();
1165 try {
1166 lock2.getWaitingThreads(c);
1167 shouldThrow();
1168 } catch (IllegalArgumentException success) {}
1169 }
1170
1171 /**
1172 * getWaitingThreads throws IMSE if not locked
1173 */
1174 public void testGetWaitingThreadsIMSE() {
1175 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1176 final Condition c = lock.writeLock().newCondition();
1177 try {
1178 lock.getWaitingThreads(c);
1179 shouldThrow();
1180 } catch (IllegalMonitorStateException success) {}
1181 }
1182
1183
1184 /**
1185 * hasWaiters returns true when a thread is waiting, else false
1186 */
1187 public void testHasWaiters() throws InterruptedException {
1188 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1189 final Condition c = lock.writeLock().newCondition();
1190 Thread t = newStartedThread(new CheckedRunnable() {
1191 public void realRun() throws InterruptedException {
1192 lock.writeLock().lock();
1193 assertFalse(lock.hasWaiters(c));
1194 assertEquals(0, lock.getWaitQueueLength(c));
1195 c.await();
1196 lock.writeLock().unlock();
1197 }});
1198
1199 Thread.sleep(SHORT_DELAY_MS);
1200 lock.writeLock().lock();
1201 assertTrue(lock.hasWaiters(c));
1202 assertEquals(1, lock.getWaitQueueLength(c));
1203 c.signal();
1204 lock.writeLock().unlock();
1205 Thread.sleep(SHORT_DELAY_MS);
1206 lock.writeLock().lock();
1207 assertFalse(lock.hasWaiters(c));
1208 assertEquals(0, lock.getWaitQueueLength(c));
1209 lock.writeLock().unlock();
1210 t.join(SHORT_DELAY_MS);
1211 assertFalse(t.isAlive());
1212 }
1213
1214 /**
1215 * getWaitQueueLength returns number of waiting threads
1216 */
1217 public void testGetWaitQueueLength() throws InterruptedException {
1218 final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1219 final Condition c = lock.writeLock().newCondition();
1220 Thread t = newStartedThread(new CheckedRunnable() {
1221 public void realRun() throws InterruptedException {
1222 lock.writeLock().lock();
1223 assertFalse(lock.hasWaiters(c));
1224 assertEquals(0, lock.getWaitQueueLength(c));
1225 c.await();
1226 lock.writeLock().unlock();
1227 }});
1228
1229 Thread.sleep(SHORT_DELAY_MS);
1230 lock.writeLock().lock();
1231 assertTrue(lock.hasWaiters(c));
1232 assertEquals(1, lock.getWaitQueueLength(c));
1233 c.signal();
1234 lock.writeLock().unlock();
1235 Thread.sleep(SHORT_DELAY_MS);
1236 lock.writeLock().lock();
1237 assertFalse(lock.hasWaiters(c));
1238 assertEquals(0, lock.getWaitQueueLength(c));
1239 lock.writeLock().unlock();
1240 t.join(SHORT_DELAY_MS);
1241 assertFalse(t.isAlive());
1242 }
1243
1244
1245 /**
1246 * getWaitingThreads returns only and all waiting threads
1247 */
1248 public void testGetWaitingThreads() throws InterruptedException {
1249 final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
1250 final Condition c = lock.writeLock().newCondition();
1251 Thread t1 = new Thread(new CheckedRunnable() {
1252 public void realRun() throws InterruptedException {
1253 lock.writeLock().lock();
1254 assertTrue(lock.getWaitingThreads(c).isEmpty());
1255 c.await();
1256 lock.writeLock().unlock();
1257 }});
1258
1259 Thread t2 = new Thread(new CheckedRunnable() {
1260 public void realRun() throws InterruptedException {
1261 lock.writeLock().lock();
1262 assertFalse(lock.getWaitingThreads(c).isEmpty());
1263 c.await();
1264 lock.writeLock().unlock();
1265 }});
1266
1267 lock.writeLock().lock();
1268 assertTrue(lock.getWaitingThreads(c).isEmpty());
1269 lock.writeLock().unlock();
1270 t1.start();
1271 Thread.sleep(SHORT_DELAY_MS);
1272 t2.start();
1273 Thread.sleep(SHORT_DELAY_MS);
1274 lock.writeLock().lock();
1275 assertTrue(lock.hasWaiters(c));
1276 assertTrue(lock.getWaitingThreads(c).contains(t1));
1277 assertTrue(lock.getWaitingThreads(c).contains(t2));
1278 c.signalAll();
1279 lock.writeLock().unlock();
1280 Thread.sleep(SHORT_DELAY_MS);
1281 lock.writeLock().lock();
1282 assertFalse(lock.hasWaiters(c));
1283 assertTrue(lock.getWaitingThreads(c).isEmpty());
1284 lock.writeLock().unlock();
1285 t1.join(SHORT_DELAY_MS);
1286 t2.join(SHORT_DELAY_MS);
1287 assertFalse(t1.isAlive());
1288 assertFalse(t2.isAlive());
1289 }
1290
1291 /**
1292 * toString indicates current lock state
1293 */
1294 public void testToString() {
1295 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1296 String us = lock.toString();
1297 assertTrue(us.indexOf("Write locks = 0") >= 0);
1298 assertTrue(us.indexOf("Read locks = 0") >= 0);
1299 lock.writeLock().lock();
1300 String ws = lock.toString();
1301 assertTrue(ws.indexOf("Write locks = 1") >= 0);
1302 assertTrue(ws.indexOf("Read locks = 0") >= 0);
1303 lock.writeLock().unlock();
1304 lock.readLock().lock();
1305 lock.readLock().lock();
1306 String rs = lock.toString();
1307 assertTrue(rs.indexOf("Write locks = 0") >= 0);
1308 assertTrue(rs.indexOf("Read locks = 2") >= 0);
1309 }
1310
1311 /**
1312 * readLock.toString indicates current lock state
1313 */
1314 public void testReadLockToString() {
1315 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1316 String us = lock.readLock().toString();
1317 assertTrue(us.indexOf("Read locks = 0") >= 0);
1318 lock.readLock().lock();
1319 lock.readLock().lock();
1320 String rs = lock.readLock().toString();
1321 assertTrue(rs.indexOf("Read locks = 2") >= 0);
1322 }
1323
1324 /**
1325 * writeLock.toString indicates current lock state
1326 */
1327 public void testWriteLockToString() {
1328 ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1329 String us = lock.writeLock().toString();
1330 assertTrue(us.indexOf("Unlocked") >= 0);
1331 lock.writeLock().lock();
1332 String ls = lock.writeLock().toString();
1333 assertTrue(ls.indexOf("Locked") >= 0);
1334 }
1335
1336 }