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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines