ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
Revision: 1.5
Committed: Fri Sep 26 15:33:13 2003 UTC (20 years, 7 months ago) by dl
Branch: MAIN
CVS Tags: JSR166_NOV3_FREEZE
Changes since 1.4: +2 -2 lines
Log Message:
Javadoc fixes

File Contents

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