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.12 by dl, Sat Dec 27 19:26:43 2003 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines