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.5 by dl, Fri Sep 26 15:33:13 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 JSR166TestCase {
16      public static void main(String[] args) {
# Line 18 | Line 20 | public class ReentrantReadWriteLockTest
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 +    /**
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
# Line 25 | Line 79 | public class ReentrantReadWriteLockTest
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  
# Line 37 | Line 103 | public class ReentrantReadWriteLockTest
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 +
139 +    /**
140       * write-unlocking an unlocked lock throws IllegalMonitorStateException
141       */
142      public void testUnlock_IllegalMonitorStateException() {
# Line 750 | Line 844 | public class ReentrantReadWriteLockTest
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