ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantReadWriteLockTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ReentrantReadWriteLockTest.java (file contents):
Revision 1.1 by dl, Sun Aug 31 19:24:55 2003 UTC vs.
Revision 1.11 by dl, Sat Dec 27 18:27:02 2003 UTC

# Line 8 | Line 8
8   import junit.framework.*;
9   import java.util.concurrent.locks.*;
10   import java.util.concurrent.*;
11 + import java.io.*;
12 + import java.util.*;
13  
14 < public class ReentrantReadWriteLockTest extends TestCase {
13 <    static int HOLD_COUNT_TEST_LIMIT = 20;
14 <    
14 > public class ReentrantReadWriteLockTest extends JSR166TestCase {
15      public static void main(String[] args) {
16          junit.textui.TestRunner.run (suite());  
17      }
18    
18      public static Test suite() {
19          return new TestSuite(ReentrantReadWriteLockTest.class);
20      }
21  
22 +    /**
23 +     * A runnable calling lockInterruptibly
24 +     */
25 +    class InterruptibleLockRunnable implements Runnable {
26 +        final ReentrantReadWriteLock lock;
27 +        InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
28 +        public void run() {
29 +            try {
30 +                lock.writeLock().lockInterruptibly();
31 +            } catch(InterruptedException success){}
32 +        }
33 +    }
34 +
35  
36 <    private static long SHORT_DELAY_MS = 100;
37 <    private static long MEDIUM_DELAY_MS = 1000;
38 <    private static long LONG_DELAY_MS = 10000;
27 <
28 <    /*
29 <     * Unlocks an unlocked lock, throws Illegal Monitor State
30 <     *
36 >    /**
37 >     * A runnable calling lockInterruptibly that expects to be
38 >     * interrupted
39       */
40 +    class InterruptedLockRunnable implements Runnable {
41 +        final ReentrantReadWriteLock lock;
42 +        InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
43 +        public void run() {
44 +            try {
45 +                lock.writeLock().lockInterruptibly();
46 +                threadShouldThrow();
47 +            } catch(InterruptedException success){}
48 +        }
49 +    }
50 +
51 +    /**
52 +     * Subclass to expose protected methods
53 +     */
54 +    static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
55 +        PublicReentrantReadWriteLock() { super(); }
56 +        public Collection<Thread> getQueuedThreads() {
57 +            return super.getQueuedThreads();
58 +        }
59 +    }
60 +
61 +    /**
62 +     * Constructor sets given fairness, and is in unlocked state
63 +     */
64 +    public void testConstructor() {
65 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
66 +        assertFalse(rl.isFair());
67 +        assertFalse(rl.isWriteLocked());
68 +        assertEquals(0, rl.getReadLockCount());
69 +        ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
70 +        assertTrue(r2.isFair());
71 +        assertFalse(r2.isWriteLocked());
72 +        assertEquals(0, r2.getReadLockCount());
73 +    }
74 +
75 +    /**
76 +     * write-locking and read-locking an unlocked lock succeed
77 +     */
78 +    public void testLock() {
79 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
80 +        rl.writeLock().lock();
81 +        assertTrue(rl.isWriteLocked());
82 +        assertTrue(rl.isWriteLockedByCurrentThread());
83 +        assertEquals(0, rl.getReadLockCount());
84 +        rl.writeLock().unlock();
85 +        assertFalse(rl.isWriteLocked());
86 +        assertFalse(rl.isWriteLockedByCurrentThread());
87 +        assertEquals(0, rl.getReadLockCount());
88 +        rl.readLock().lock();
89 +        assertFalse(rl.isWriteLocked());
90 +        assertFalse(rl.isWriteLockedByCurrentThread());
91 +        assertEquals(1, rl.getReadLockCount());
92 +        rl.readLock().unlock();
93 +        assertFalse(rl.isWriteLocked());
94 +        assertFalse(rl.isWriteLockedByCurrentThread());
95 +        assertEquals(0, rl.getReadLockCount());
96 +    }
97 +
98 +
99 +    /**
100 +     * locking an unlocked fair lock succeeds
101 +     */
102 +    public void testFairLock() {
103 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
104 +        rl.writeLock().lock();
105 +        assertTrue(rl.isWriteLocked());
106 +        assertTrue(rl.isWriteLockedByCurrentThread());
107 +        assertEquals(0, rl.getReadLockCount());
108 +        rl.writeLock().unlock();
109 +        assertFalse(rl.isWriteLocked());
110 +        assertFalse(rl.isWriteLockedByCurrentThread());
111 +        assertEquals(0, rl.getReadLockCount());
112 +        rl.readLock().lock();
113 +        assertFalse(rl.isWriteLocked());
114 +        assertFalse(rl.isWriteLockedByCurrentThread());
115 +        assertEquals(1, rl.getReadLockCount());
116 +        rl.readLock().unlock();
117 +        assertFalse(rl.isWriteLocked());
118 +        assertFalse(rl.isWriteLockedByCurrentThread());
119 +        assertEquals(0, rl.getReadLockCount());
120 +    }
121 +
122 +    /**
123 +     * getWriteHoldCount returns number of recursive holds
124 +     */
125 +    public void testGetHoldCount() {
126 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
127 +        for(int i = 1; i <= SIZE; i++) {
128 +            lock.writeLock().lock();
129 +            assertEquals(i,lock.getWriteHoldCount());
130 +        }
131 +        for(int i = SIZE; i > 0; i--) {
132 +            lock.writeLock().unlock();
133 +            assertEquals(i-1,lock.getWriteHoldCount());
134 +        }
135 +    }
136      
137 <    public void testIllegalMonitorStateException(){
137 >
138 >    /**
139 >     * write-unlocking an unlocked lock throws IllegalMonitorStateException
140 >     */
141 >    public void testUnlock_IllegalMonitorStateException() {
142          ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
143 <        try{
143 >        try {
144              rl.writeLock().unlock();
145 <            fail("Should of thown Illegal Monitor State Exception");
145 >            shouldThrow();
146 >        } catch(IllegalMonitorStateException success){}
147 >    }
148  
39        }catch(IllegalMonitorStateException sucess){}
149  
150 +    /**
151 +     * write-lockInterruptibly is interruptible
152 +     */
153 +    public void testWriteLockInterruptibly_Interrupted() {
154 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
155 +        lock.writeLock().lock();
156 +        Thread t = new Thread(new Runnable() {
157 +                public void run() {
158 +                    try {
159 +                        lock.writeLock().lockInterruptibly();
160 +                        threadShouldThrow();
161 +                    } catch(InterruptedException success){}
162 +                }
163 +            });
164 +        try {
165 +            t.start();
166 +            t.interrupt();
167 +            lock.writeLock().unlock();
168 +            t.join();
169 +        } catch(Exception e){
170 +            unexpectedException();
171 +        }
172 +    }
173 +
174 +    /**
175 +     * timed write-trylock is interruptible
176 +     */
177 +    public void testWriteTryLock_Interrupted() {
178 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
179 +        lock.writeLock().lock();
180 +        Thread t = new Thread(new Runnable() {
181 +                public void run() {
182 +                    try {
183 +                        lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
184 +                        threadShouldThrow();
185 +                    } catch(InterruptedException success){}
186 +                }
187 +            });
188 +        try {
189 +            t.start();
190 +            t.interrupt();
191 +            lock.writeLock().unlock();
192 +            t.join();
193 +        } catch(Exception e){
194 +            unexpectedException();
195 +        }
196 +    }
197 +
198 +    /**
199 +     * read-lockInterruptibly is interruptible
200 +     */
201 +    public void testReadLockInterruptibly_Interrupted() {
202 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
203 +        lock.writeLock().lock();
204 +        Thread t = new Thread(new Runnable() {
205 +                public void run() {
206 +                    try {
207 +                        lock.readLock().lockInterruptibly();
208 +                        threadShouldThrow();
209 +                    } catch(InterruptedException success){}
210 +                }
211 +            });
212 +        try {
213 +            t.start();
214 +            t.interrupt();
215 +            lock.writeLock().unlock();
216 +            t.join();
217 +        } catch(Exception e){
218 +            unexpectedException();
219 +        }
220 +    }
221  
222 +    /**
223 +     * timed read-trylock is interruptible
224 +     */
225 +    public void testReadTryLock_Interrupted() {
226 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
227 +        lock.writeLock().lock();
228 +        Thread t = new Thread(new Runnable() {
229 +                public void run() {
230 +                    try {
231 +                        lock.readLock().tryLock(1000,TimeUnit.MILLISECONDS);
232 +                        threadShouldThrow();
233 +                    } catch(InterruptedException success){}
234 +                }
235 +            });
236 +        try {
237 +            t.start();
238 +            t.interrupt();
239 +            t.join();
240 +        } catch(Exception e){
241 +            unexpectedException();
242 +        }
243      }
244 +
245      
246 <    /*
247 <     * makes a lock, locks it, tries to aquire the lock in another thread
248 <     * interrupts that thread and waits for an interrupted Exception to
249 <     * be thrown.
246 >    /**
247 >     * write-trylock fails if locked
248 >     */
249 >    public void testWriteTryLockWhenLocked() {
250 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
251 >        lock.writeLock().lock();
252 >        Thread t = new Thread(new Runnable() {
253 >                public void run() {
254 >                    threadAssertFalse(lock.writeLock().tryLock());
255 >                }
256 >            });
257 >        try {
258 >            t.start();
259 >            t.join();
260 >            lock.writeLock().unlock();
261 >        } catch(Exception e){
262 >            unexpectedException();
263 >        }
264 >    }
265 >
266 >    /**
267 >     * read-trylock fails if locked
268       */
269 +    public void testReadTryLockWhenLocked() {
270 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
271 +        lock.writeLock().lock();
272 +        Thread t = new Thread(new Runnable() {
273 +                public void run() {
274 +                    threadAssertFalse(lock.readLock().tryLock());
275 +                }
276 +            });
277 +        try {
278 +            t.start();
279 +            t.join();
280 +            lock.writeLock().unlock();
281 +        } catch(Exception e){
282 +            unexpectedException();
283 +        }
284 +    }
285  
286 <    public void testInterruptedException(){
286 >    /**
287 >     * Multiple threads can hold a read lock when not write-locked
288 >     */
289 >    public void testMultipleReadLocks() {
290 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
291 >        lock.readLock().lock();
292 >        Thread t = new Thread(new Runnable() {
293 >                public void run() {
294 >                    threadAssertTrue(lock.readLock().tryLock());
295 >                    lock.readLock().unlock();
296 >                }
297 >            });
298 >        try {
299 >            t.start();
300 >            t.join();
301 >            lock.readLock().unlock();
302 >        } catch(Exception e){
303 >            unexpectedException();
304 >        }
305 >    }
306 >
307 >    /**
308 >     * A writelock succeeds after reading threads unlock
309 >     */
310 >    public void testWriteAfterMultipleReadLocks() {
311 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
312 >        lock.readLock().lock();
313 >        Thread t1 = new Thread(new Runnable() {
314 >                public void run() {
315 >                    lock.readLock().lock();
316 >                    lock.readLock().unlock();
317 >                }
318 >            });
319 >        Thread t2 = new Thread(new Runnable() {
320 >                public void run() {
321 >                    lock.writeLock().lock();
322 >                    lock.writeLock().unlock();
323 >                }
324 >            });
325 >
326 >        try {
327 >            t1.start();
328 >            t2.start();
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 >        } catch(Exception e){
337 >            unexpectedException();
338 >        }
339 >    }
340 >
341 >    /**
342 >     * Readlocks succeed after a writing thread unlocks
343 >     */
344 >    public void testReadAfterWriteLock() {
345          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
346          lock.writeLock().lock();
347 +        Thread t1 = new Thread(new Runnable() {
348 +                public void run() {
349 +                    lock.readLock().lock();
350 +                    lock.readLock().unlock();
351 +                }
352 +            });
353 +        Thread t2 = new Thread(new Runnable() {
354 +                public void run() {
355 +                    lock.readLock().lock();
356 +                    lock.readLock().unlock();
357 +                }
358 +            });
359 +
360 +        try {
361 +            t1.start();
362 +            t2.start();
363 +            Thread.sleep(SHORT_DELAY_MS);
364 +            lock.writeLock().unlock();
365 +            t1.join(MEDIUM_DELAY_MS);
366 +            t2.join(MEDIUM_DELAY_MS);
367 +            assertTrue(!t1.isAlive());
368 +            assertTrue(!t2.isAlive());
369 +          
370 +        } catch(Exception e){
371 +            unexpectedException();
372 +        }
373 +    }
374 +
375 +
376 +    /**
377 +     * Read trylock succeeds if readlocked but not writelocked
378 +     */
379 +    public void testTryLockWhenReadLocked() {
380 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
381 +        lock.readLock().lock();
382          Thread t = new Thread(new Runnable() {
383 <                public void run(){
384 <                    try{
385 <                        lock.writeLock().lockInterruptibly();
57 <                        fail("should throw");
58 <                    }catch(InterruptedException sucess){}
383 >                public void run() {
384 >                    threadAssertTrue(lock.readLock().tryLock());
385 >                    lock.readLock().unlock();
386                  }
387              });
388 <        t.start();
389 <        t.interrupt();
390 <        lock.writeLock().unlock();
388 >        try {
389 >            t.start();
390 >            t.join();
391 >            lock.readLock().unlock();
392 >        } catch(Exception e){
393 >            unexpectedException();
394 >        }
395      }
396  
397 <    /*
398 <     * tests for interrupted exception on a timed wait
399 <     *
397 >    
398 >
399 >    /**
400 >     * write trylock fails when readlocked
401       */
402 +    public void testWriteTryLockWhenReadLocked() {
403 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
404 +        lock.readLock().lock();
405 +        Thread t = new Thread(new Runnable() {
406 +                public void run() {
407 +                    threadAssertFalse(lock.writeLock().tryLock());
408 +                }
409 +            });
410 +        try {
411 +            t.start();
412 +            t.join();
413 +            lock.readLock().unlock();
414 +        } catch(Exception e){
415 +            unexpectedException();
416 +        }
417 +    }
418 +
419      
420  
421 <    public void testInterruptedException2(){
421 >    /**
422 >     * write timed trylock times out if locked
423 >     */
424 >    public void testWriteTryLock_Timeout() {
425          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
426          lock.writeLock().lock();
427          Thread t = new Thread(new Runnable() {
428 <                public void run(){
429 <                    try{
430 <                        lock.writeLock().tryLock(1000,TimeUnit.MILLISECONDS);
431 <                        fail("should throw");
432 <                    }catch(InterruptedException sucess){}
428 >                public void run() {
429 >                    try {
430 >                        threadAssertFalse(lock.writeLock().tryLock(1, TimeUnit.MILLISECONDS));
431 >                    } catch (Exception ex) {
432 >                        threadUnexpectedException();
433 >                    }
434 >                }
435 >            });
436 >        try {
437 >            t.start();
438 >            t.join();
439 >            lock.writeLock().unlock();
440 >        } catch(Exception e){
441 >            unexpectedException();
442 >        }
443 >    }
444 >
445 >    /**
446 >     * read timed trylock times out if write-locked
447 >     */
448 >    public void testReadTryLock_Timeout() {
449 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
450 >        lock.writeLock().lock();
451 >        Thread t = new Thread(new Runnable() {
452 >                public void run() {
453 >                    try {
454 >                        threadAssertFalse(lock.readLock().tryLock(1, TimeUnit.MILLISECONDS));
455 >                    } catch (Exception ex) {
456 >                        threadUnexpectedException();
457 >                    }
458 >                }
459 >            });
460 >        try {
461 >            t.start();
462 >            t.join();
463 >            lock.writeLock().unlock();
464 >        } catch(Exception e){
465 >            unexpectedException();
466 >        }
467 >    }
468 >
469 >
470 >    /**
471 >     * write lockInterruptibly succeeds if lock free else is interruptible
472 >     */
473 >    public void testWriteLockInterruptibly() {
474 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
475 >        try {
476 >            lock.writeLock().lockInterruptibly();
477 >        } catch(Exception e) {
478 >            unexpectedException();
479 >        }
480 >        Thread t = new Thread(new Runnable() {
481 >                public void run() {
482 >                    try {
483 >                        lock.writeLock().lockInterruptibly();
484 >                        threadShouldThrow();
485 >                    }
486 >                    catch(InterruptedException success) {
487 >                    }
488                  }
489              });
490 <        t.start();
491 <        t.interrupt();
490 >        try {
491 >            t.start();
492 >            t.interrupt();
493 >            t.join();
494 >            lock.writeLock().unlock();
495 >        } catch(Exception e){
496 >            unexpectedException();
497 >        }
498      }
499  
500 <    
500 >    /**
501 >     *  read lockInterruptibly succeeds if lock free else is interruptible
502 >     */
503 >    public void testReadLockInterruptibly() {
504 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
505 >        try {
506 >            lock.writeLock().lockInterruptibly();
507 >        } catch(Exception e) {
508 >            unexpectedException();
509 >        }
510 >        Thread t = new Thread(new Runnable() {
511 >                public void run() {
512 >                    try {
513 >                        lock.readLock().lockInterruptibly();
514 >                        threadShouldThrow();
515 >                    }
516 >                    catch(InterruptedException success) {
517 >                    }
518 >                }
519 >            });
520 >        try {
521 >            t.start();
522 >            t.interrupt();
523 >            t.join();
524 >            lock.writeLock().unlock();
525 >        } catch(Exception e){
526 >            unexpectedException();
527 >        }
528 >    }
529  
530 <    /*
531 <     * current thread locks interruptibly the thread
91 <     * another thread tries to aquire the lock and blocks
92 <     * on the call. interrupt the attempted aquireLock
93 <     * assert that the first lock() call actually locked the lock
94 <     * assert that the current thread is the one holding the lock
530 >    /**
531 >     * Calling await without holding lock throws IllegalMonitorStateException
532       */
533 +    public void testAwait_IllegalMonitor() {
534 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
535 +        final Condition c = lock.writeLock().newCondition();
536 +        try {
537 +            c.await();
538 +            shouldThrow();
539 +        }
540 +        catch (IllegalMonitorStateException success) {
541 +        }
542 +        catch (Exception ex) {
543 +            shouldThrow();
544 +        }
545 +    }
546  
547 <    public void testLockedInterruptibly() {
547 >    /**
548 >     * Calling signal without holding lock throws IllegalMonitorStateException
549 >     */
550 >    public void testSignal_IllegalMonitor() {
551 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
552 >        final Condition c = lock.writeLock().newCondition();
553 >        try {
554 >            c.signal();
555 >            shouldThrow();
556 >        }
557 >        catch (IllegalMonitorStateException success) {
558 >        }
559 >        catch (Exception ex) {
560 >            unexpectedException();
561 >        }
562 >    }
563 >
564 >    /**
565 >     * awaitNanos without a signal times out
566 >     */
567 >    public void testAwaitNanos_Timeout() {
568 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
569 >        final Condition c = lock.writeLock().newCondition();
570 >        try {
571 >            lock.writeLock().lock();
572 >            long t = c.awaitNanos(100);
573 >            assertTrue(t <= 0);
574 >            lock.writeLock().unlock();
575 >        }
576 >        catch (Exception ex) {
577 >            unexpectedException();
578 >        }
579 >    }
580 >
581 >
582 >    /**
583 >     *  timed await without a signal times out
584 >     */
585 >    public void testAwait_Timeout() {
586 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
587 >        final Condition c = lock.writeLock().newCondition();
588 >        try {
589 >            lock.writeLock().lock();
590 >            assertFalse(c.await(10, TimeUnit.MILLISECONDS));
591 >            lock.writeLock().unlock();
592 >        }
593 >        catch (Exception ex) {
594 >            unexpectedException();
595 >        }
596 >    }
597 >
598 >    /**
599 >     * awaitUntil without a signal times out
600 >     */
601 >    public void testAwaitUntil_Timeout() {
602 >        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
603 >        final Condition c = lock.writeLock().newCondition();
604 >        try {
605 >            lock.writeLock().lock();
606 >            java.util.Date d = new java.util.Date();
607 >            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
608 >            lock.writeLock().unlock();
609 >        }
610 >        catch (Exception ex) {
611 >            unexpectedException();
612 >        }
613 >    }
614 >
615 >    /**
616 >     * await returns when signalled
617 >     */
618 >    public void testAwait() {
619          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
620 <        try {lock.writeLock().lockInterruptibly();} catch(Exception e) {}
620 >        final Condition c = lock.writeLock().newCondition();
621          Thread t = new Thread(new Runnable() {
622                  public void run() {
623                      try {
624 <                        lock.writeLock().lockInterruptibly();
625 <                        fail("Failed to generate an Interrupted Exception");
624 >                        lock.writeLock().lock();
625 >                        c.await();
626 >                        lock.writeLock().unlock();
627                      }
628 <                    catch(InterruptedException e) {}
628 >                    catch(InterruptedException e) {
629 >                        threadUnexpectedException();
630 >                    }
631                  }
632              });
633 <        t.start();
634 <        t.interrupt();
633 >
634 >        try {
635 >            t.start();
636 >            Thread.sleep(SHORT_DELAY_MS);
637 >            lock.writeLock().lock();
638 >            c.signal();
639 >            lock.writeLock().unlock();
640 >            t.join(SHORT_DELAY_MS);
641 >            assertFalse(t.isAlive());
642 >        }
643 >        catch (Exception ex) {
644 >            unexpectedException();
645 >        }
646      }
112    
647  
648 +    /**
649 +     * awaitUninterruptibly doesn't abort on interrupt
650 +     */
651 +    public void testAwaitUninterruptibly() {
652 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
653 +        final Condition c = lock.writeLock().newCondition();
654 +        Thread t = new Thread(new Runnable() {
655 +                public void run() {
656 +                    lock.writeLock().lock();
657 +                    c.awaitUninterruptibly();
658 +                    lock.writeLock().unlock();
659 +                }
660 +            });
661 +
662 +        try {
663 +            t.start();
664 +            Thread.sleep(SHORT_DELAY_MS);
665 +            t.interrupt();
666 +            lock.writeLock().lock();
667 +            c.signal();
668 +            lock.writeLock().unlock();
669 +            assert(t.isInterrupted());
670 +            t.join(SHORT_DELAY_MS);
671 +            assertFalse(t.isAlive());
672 +        }
673 +        catch (Exception ex) {
674 +            unexpectedException();
675 +        }
676 +    }
677 +
678 +    /**
679 +     * await is interruptible
680 +     */
681 +    public void testAwait_Interrupt() {
682 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
683 +        final Condition c = lock.writeLock().newCondition();
684 +        Thread t = new Thread(new Runnable() {
685 +                public void run() {
686 +                    try {
687 +                        lock.writeLock().lock();
688 +                        c.await();
689 +                        lock.writeLock().unlock();
690 +                        threadShouldThrow();
691 +                    }
692 +                    catch(InterruptedException success) {
693 +                    }
694 +                }
695 +            });
696 +
697 +        try {
698 +            t.start();
699 +            Thread.sleep(SHORT_DELAY_MS);
700 +            t.interrupt();
701 +            t.join(SHORT_DELAY_MS);
702 +            assertFalse(t.isAlive());
703 +        }
704 +        catch (Exception ex) {
705 +            unexpectedException();
706 +        }
707 +    }
708 +
709 +    /**
710 +     * awaitNanos is interruptible
711 +     */
712 +    public void testAwaitNanos_Interrupt() {
713 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
714 +        final Condition c = lock.writeLock().newCondition();
715 +        Thread t = new Thread(new Runnable() {
716 +                public void run() {
717 +                    try {
718 +                        lock.writeLock().lock();
719 +                        c.awaitNanos(SHORT_DELAY_MS * 2 * 1000000);
720 +                        lock.writeLock().unlock();
721 +                        threadShouldThrow();
722 +                    }
723 +                    catch(InterruptedException success) {
724 +                    }
725 +                }
726 +            });
727 +
728 +        try {
729 +            t.start();
730 +            Thread.sleep(SHORT_DELAY_MS);
731 +            t.interrupt();
732 +            t.join(SHORT_DELAY_MS);
733 +            assertFalse(t.isAlive());
734 +        }
735 +        catch (Exception ex) {
736 +            unexpectedException();
737 +        }
738 +    }
739 +
740 +    /**
741 +     * awaitUntil is interruptible
742 +     */
743 +    public void testAwaitUntil_Interrupt() {
744 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
745 +        final Condition c = lock.writeLock().newCondition();
746 +        Thread t = new Thread(new Runnable() {
747 +                public void run() {
748 +                    try {
749 +                        lock.writeLock().lock();
750 +                        java.util.Date d = new java.util.Date();
751 +                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
752 +                        lock.writeLock().unlock();
753 +                        threadShouldThrow();
754 +                    }
755 +                    catch(InterruptedException success) {
756 +                    }
757 +                }
758 +            });
759 +
760 +        try {
761 +            t.start();
762 +            Thread.sleep(SHORT_DELAY_MS);
763 +            t.interrupt();
764 +            t.join(SHORT_DELAY_MS);
765 +            assertFalse(t.isAlive());
766 +        }
767 +        catch (Exception ex) {
768 +            unexpectedException();
769 +        }
770 +    }
771 +
772 +    /**
773 +     * signalAll wakes up all threads
774 +     */
775 +    public void testSignalAll() {
776 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
777 +        final Condition c = lock.writeLock().newCondition();
778 +        Thread t1 = new Thread(new Runnable() {
779 +                public void run() {
780 +                    try {
781 +                        lock.writeLock().lock();
782 +                        c.await();
783 +                        lock.writeLock().unlock();
784 +                    }
785 +                    catch(InterruptedException e) {
786 +                        threadUnexpectedException();
787 +                    }
788 +                }
789 +            });
790 +
791 +        Thread t2 = new Thread(new Runnable() {
792 +                public void run() {
793 +                    try {
794 +                        lock.writeLock().lock();
795 +                        c.await();
796 +                        lock.writeLock().unlock();
797 +                    }
798 +                    catch(InterruptedException e) {
799 +                        threadUnexpectedException();
800 +                    }
801 +                }
802 +            });
803 +
804 +        try {
805 +            t1.start();
806 +            t2.start();
807 +            Thread.sleep(SHORT_DELAY_MS);
808 +            lock.writeLock().lock();
809 +            c.signalAll();
810 +            lock.writeLock().unlock();
811 +            t1.join(SHORT_DELAY_MS);
812 +            t2.join(SHORT_DELAY_MS);
813 +            assertFalse(t1.isAlive());
814 +            assertFalse(t2.isAlive());
815 +        }
816 +        catch (Exception ex) {
817 +            unexpectedException();
818 +        }
819 +    }
820 +
821 +    /**
822 +     * A serialized lock deserializes as unlocked
823 +     */
824 +    public void testSerialization() {
825 +        ReentrantReadWriteLock l = new ReentrantReadWriteLock();
826 +        l.readLock().lock();
827 +        l.readLock().unlock();
828 +
829 +        try {
830 +            ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
831 +            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
832 +            out.writeObject(l);
833 +            out.close();
834 +
835 +            ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
836 +            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
837 +            ReentrantReadWriteLock r = (ReentrantReadWriteLock) in.readObject();
838 +            r.readLock().lock();
839 +            r.readLock().unlock();
840 +        } catch(Exception e){
841 +            e.printStackTrace();
842 +            unexpectedException();
843 +        }
844 +    }
845 +
846 +    /**
847 +     * getQueueLength reports number of waiting threads
848 +     */
849 +    public void testGetQueueLength() {
850 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
851 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
852 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
853 +        try {
854 +            assertEquals(0, lock.getQueueLength());
855 +            lock.writeLock().lock();
856 +            t1.start();
857 +            Thread.sleep(SHORT_DELAY_MS);
858 +            assertEquals(1, lock.getQueueLength());
859 +            t2.start();
860 +            Thread.sleep(SHORT_DELAY_MS);
861 +            assertEquals(2, lock.getQueueLength());
862 +            t1.interrupt();
863 +            Thread.sleep(SHORT_DELAY_MS);
864 +            assertEquals(1, lock.getQueueLength());
865 +            lock.writeLock().unlock();
866 +            Thread.sleep(SHORT_DELAY_MS);
867 +            assertEquals(0, lock.getQueueLength());
868 +            t1.join();
869 +            t2.join();
870 +        } catch(Exception e){
871 +            unexpectedException();
872 +        }
873 +    }
874 +
875 +    /**
876 +     * getQueuedThreads includes waiting threads
877 +     */
878 +    public void testGetQueuedThreads() {
879 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
880 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
881 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
882 +        try {
883 +            assertTrue(lock.getQueuedThreads().isEmpty());
884 +            lock.writeLock().lock();
885 +            assertTrue(lock.getQueuedThreads().isEmpty());
886 +            t1.start();
887 +            Thread.sleep(SHORT_DELAY_MS);
888 +            assertTrue(lock.getQueuedThreads().contains(t1));
889 +            t2.start();
890 +            Thread.sleep(SHORT_DELAY_MS);
891 +            assertTrue(lock.getQueuedThreads().contains(t1));
892 +            assertTrue(lock.getQueuedThreads().contains(t2));
893 +            t1.interrupt();
894 +            Thread.sleep(SHORT_DELAY_MS);
895 +            assertFalse(lock.getQueuedThreads().contains(t1));
896 +            assertTrue(lock.getQueuedThreads().contains(t2));
897 +            lock.writeLock().unlock();
898 +            Thread.sleep(SHORT_DELAY_MS);
899 +            assertTrue(lock.getQueuedThreads().isEmpty());
900 +            t1.join();
901 +            t2.join();
902 +        } catch(Exception e){
903 +            unexpectedException();
904 +        }
905 +    }
906 +
907 +    /**
908 +     * hasWaiters returns true when a thread is waiting, else false
909 +     */
910 +    public void testHasWaiters() {
911 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
912 +        final AbstractQueuedSynchronizer.ConditionObject c = (lock.writeLock().newCondition());
913 +        Thread t = new Thread(new Runnable() {
914 +                public void run() {
915 +                    try {
916 +                        lock.writeLock().lock();
917 +                        threadAssertFalse(c.hasWaiters());
918 +                        threadAssertEquals(0, c.getWaitQueueLength());
919 +                        c.await();
920 +                        lock.writeLock().unlock();
921 +                    }
922 +                    catch(InterruptedException e) {
923 +                        threadUnexpectedException();
924 +                    }
925 +                }
926 +            });
927 +
928 +        try {
929 +            t.start();
930 +            Thread.sleep(SHORT_DELAY_MS);
931 +            lock.writeLock().lock();
932 +            assertTrue(c.hasWaiters());
933 +            assertEquals(1, c.getWaitQueueLength());
934 +            c.signal();
935 +            lock.writeLock().unlock();
936 +            Thread.sleep(SHORT_DELAY_MS);
937 +            lock.writeLock().lock();
938 +            assertFalse(c.hasWaiters());
939 +            assertEquals(0, c.getWaitQueueLength());
940 +            lock.writeLock().unlock();
941 +            t.join(SHORT_DELAY_MS);
942 +            assertFalse(t.isAlive());
943 +        }
944 +        catch (Exception ex) {
945 +            unexpectedException();
946 +        }
947 +    }
948 +
949 +    /**
950 +     * getWaitQueueLength returns number of waiting threads
951 +     */
952 +    public void testGetWaitQueueLength() {
953 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
954 +        final AbstractQueuedSynchronizer.ConditionObject c = (lock.writeLock().newCondition());
955 +        Thread t1 = new Thread(new Runnable() {
956 +                public void run() {
957 +                    try {
958 +                        lock.writeLock().lock();
959 +                        threadAssertFalse(c.hasWaiters());
960 +                        threadAssertEquals(0, c.getWaitQueueLength());
961 +                        c.await();
962 +                        lock.writeLock().unlock();
963 +                    }
964 +                    catch(InterruptedException e) {
965 +                        threadUnexpectedException();
966 +                    }
967 +                }
968 +            });
969 +
970 +        Thread t2 = new Thread(new Runnable() {
971 +                public void run() {
972 +                    try {
973 +                        lock.writeLock().lock();
974 +                        threadAssertTrue(c.hasWaiters());
975 +                        threadAssertEquals(1, c.getWaitQueueLength());
976 +                        c.await();
977 +                        lock.writeLock().unlock();
978 +                    }
979 +                    catch(InterruptedException e) {
980 +                        threadUnexpectedException();
981 +                    }
982 +                }
983 +            });
984 +
985 +        try {
986 +            t1.start();
987 +            Thread.sleep(SHORT_DELAY_MS);
988 +            t2.start();
989 +            Thread.sleep(SHORT_DELAY_MS);
990 +            lock.writeLock().lock();
991 +            assertTrue(c.hasWaiters());
992 +            assertEquals(2, c.getWaitQueueLength());
993 +            c.signalAll();
994 +            lock.writeLock().unlock();
995 +            Thread.sleep(SHORT_DELAY_MS);
996 +            lock.writeLock().lock();
997 +            assertFalse(c.hasWaiters());
998 +            assertEquals(0, c.getWaitQueueLength());
999 +            lock.writeLock().unlock();
1000 +            t1.join(SHORT_DELAY_MS);
1001 +            t2.join(SHORT_DELAY_MS);
1002 +            assertFalse(t1.isAlive());
1003 +            assertFalse(t2.isAlive());
1004 +        }
1005 +        catch (Exception ex) {
1006 +            unexpectedException();
1007 +        }
1008 +    }
1009   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines