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.4 by dl, Sat Sep 20 18:20:08 2003 UTC vs.
Revision 1.13 by dl, Sun Dec 28 21:56:18 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 +        public Collection<Thread> getWaitingThreads(Condition c) {
61 +            return super.getWaitingThreads(c);
62 +        }
63 +    }
64  
65 <    /*
65 >    /**
66 >     * Constructor sets given fairness, and is in unlocked state
67 >     */
68 >    public void testConstructor() {
69 >        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
70 >        assertFalse(rl.isFair());
71 >        assertFalse(rl.isWriteLocked());
72 >        assertEquals(0, rl.getReadLockCount());
73 >        ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
74 >        assertTrue(r2.isFair());
75 >        assertFalse(r2.isWriteLocked());
76 >        assertEquals(0, r2.getReadLockCount());
77 >    }
78 >
79 >    /**
80       * write-locking and read-locking an unlocked lock succeed
81       */
82      public void testLock() {
83          ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
84          rl.writeLock().lock();
85 +        assertTrue(rl.isWriteLocked());
86 +        assertTrue(rl.isWriteLockedByCurrentThread());
87 +        assertEquals(0, rl.getReadLockCount());
88          rl.writeLock().unlock();
89 +        assertFalse(rl.isWriteLocked());
90 +        assertFalse(rl.isWriteLockedByCurrentThread());
91 +        assertEquals(0, rl.getReadLockCount());
92          rl.readLock().lock();
93 +        assertFalse(rl.isWriteLocked());
94 +        assertFalse(rl.isWriteLockedByCurrentThread());
95 +        assertEquals(1, rl.getReadLockCount());
96          rl.readLock().unlock();
97 +        assertFalse(rl.isWriteLocked());
98 +        assertFalse(rl.isWriteLockedByCurrentThread());
99 +        assertEquals(0, rl.getReadLockCount());
100      }
101  
102  
103 <    /*
103 >    /**
104       * locking an unlocked fair lock succeeds
105       */
106      public void testFairLock() {
107          ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
108          rl.writeLock().lock();
109 +        assertTrue(rl.isWriteLocked());
110 +        assertTrue(rl.isWriteLockedByCurrentThread());
111 +        assertEquals(0, rl.getReadLockCount());
112          rl.writeLock().unlock();
113 +        assertFalse(rl.isWriteLocked());
114 +        assertFalse(rl.isWriteLockedByCurrentThread());
115 +        assertEquals(0, rl.getReadLockCount());
116          rl.readLock().lock();
117 +        assertFalse(rl.isWriteLocked());
118 +        assertFalse(rl.isWriteLockedByCurrentThread());
119 +        assertEquals(1, rl.getReadLockCount());
120          rl.readLock().unlock();
121 +        assertFalse(rl.isWriteLocked());
122 +        assertFalse(rl.isWriteLockedByCurrentThread());
123 +        assertEquals(0, rl.getReadLockCount());
124 +    }
125 +
126 +    /**
127 +     * getWriteHoldCount returns number of recursive holds
128 +     */
129 +    public void testGetHoldCount() {
130 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
131 +        for(int i = 1; i <= SIZE; i++) {
132 +            lock.writeLock().lock();
133 +            assertEquals(i,lock.getWriteHoldCount());
134 +        }
135 +        for(int i = SIZE; i > 0; i--) {
136 +            lock.writeLock().unlock();
137 +            assertEquals(i-1,lock.getWriteHoldCount());
138 +        }
139      }
140 +    
141  
142      /**
143       * write-unlocking an unlocked lock throws IllegalMonitorStateException
# Line 750 | Line 847 | public class ReentrantReadWriteLockTest
847          }
848      }
849  
850 +    /**
851 +     * hasQueuedThreads reports whether there are waiting threads
852 +     */
853 +    public void testhasQueuedThreads() {
854 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
855 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
856 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
857 +        try {
858 +            assertFalse(lock.hasQueuedThreads());
859 +            lock.writeLock().lock();
860 +            t1.start();
861 +            Thread.sleep(SHORT_DELAY_MS);
862 +            assertTrue(lock.hasQueuedThreads());
863 +            t2.start();
864 +            Thread.sleep(SHORT_DELAY_MS);
865 +            assertTrue(lock.hasQueuedThreads());
866 +            t1.interrupt();
867 +            Thread.sleep(SHORT_DELAY_MS);
868 +            assertTrue(lock.hasQueuedThreads());
869 +            lock.writeLock().unlock();
870 +            Thread.sleep(SHORT_DELAY_MS);
871 +            assertFalse(lock.hasQueuedThreads());
872 +            t1.join();
873 +            t2.join();
874 +        } catch(Exception e){
875 +            unexpectedException();
876 +        }
877 +    }
878 +
879 +    /**
880 +     * getQueueLength reports number of waiting threads
881 +     */
882 +    public void testGetQueueLength() {
883 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
884 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
885 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
886 +        try {
887 +            assertEquals(0, lock.getQueueLength());
888 +            lock.writeLock().lock();
889 +            t1.start();
890 +            Thread.sleep(SHORT_DELAY_MS);
891 +            assertEquals(1, lock.getQueueLength());
892 +            t2.start();
893 +            Thread.sleep(SHORT_DELAY_MS);
894 +            assertEquals(2, lock.getQueueLength());
895 +            t1.interrupt();
896 +            Thread.sleep(SHORT_DELAY_MS);
897 +            assertEquals(1, lock.getQueueLength());
898 +            lock.writeLock().unlock();
899 +            Thread.sleep(SHORT_DELAY_MS);
900 +            assertEquals(0, lock.getQueueLength());
901 +            t1.join();
902 +            t2.join();
903 +        } catch(Exception e){
904 +            unexpectedException();
905 +        }
906 +    }
907 +
908 +    /**
909 +     * getQueuedThreads includes waiting threads
910 +     */
911 +    public void testGetQueuedThreads() {
912 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
913 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
914 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
915 +        try {
916 +            assertTrue(lock.getQueuedThreads().isEmpty());
917 +            lock.writeLock().lock();
918 +            assertTrue(lock.getQueuedThreads().isEmpty());
919 +            t1.start();
920 +            Thread.sleep(SHORT_DELAY_MS);
921 +            assertTrue(lock.getQueuedThreads().contains(t1));
922 +            t2.start();
923 +            Thread.sleep(SHORT_DELAY_MS);
924 +            assertTrue(lock.getQueuedThreads().contains(t1));
925 +            assertTrue(lock.getQueuedThreads().contains(t2));
926 +            t1.interrupt();
927 +            Thread.sleep(SHORT_DELAY_MS);
928 +            assertFalse(lock.getQueuedThreads().contains(t1));
929 +            assertTrue(lock.getQueuedThreads().contains(t2));
930 +            lock.writeLock().unlock();
931 +            Thread.sleep(SHORT_DELAY_MS);
932 +            assertTrue(lock.getQueuedThreads().isEmpty());
933 +            t1.join();
934 +            t2.join();
935 +        } catch(Exception e){
936 +            unexpectedException();
937 +        }
938 +    }
939 +
940 +    /**
941 +     * hasWaiters throws IAE if not owned
942 +     */
943 +    public void testHasWaitersIAE() {
944 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
945 +        final Condition c = (lock.writeLock().newCondition());
946 +        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
947 +        try {
948 +            lock2.hasWaiters(c);
949 +            shouldThrow();
950 +        } catch (IllegalArgumentException success) {
951 +        } catch (Exception ex) {
952 +            unexpectedException();
953 +        }
954 +    }
955 +
956 +    /**
957 +     * hasWaiters throws IMSE if not locked
958 +     */
959 +    public void testHasWaitersIMSE() {
960 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
961 +        final Condition c = (lock.writeLock().newCondition());
962 +        try {
963 +            lock.hasWaiters(c);
964 +            shouldThrow();
965 +        } catch (IllegalMonitorStateException success) {
966 +        } catch (Exception ex) {
967 +            unexpectedException();
968 +        }
969 +    }
970 +
971 +
972 +    /**
973 +     * getWaitQueueLength throws IAE if not owned
974 +     */
975 +    public void testGetWaitQueueLengthIAE() {
976 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
977 +        final Condition c = (lock.writeLock().newCondition());
978 +        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
979 +        try {
980 +            lock2.getWaitQueueLength(c);
981 +            shouldThrow();
982 +        } catch (IllegalArgumentException success) {
983 +        } catch (Exception ex) {
984 +            unexpectedException();
985 +        }
986 +    }
987 +
988 +    /**
989 +     * getWaitQueueLength throws IMSE if not locked
990 +     */
991 +    public void testGetWaitQueueLengthIMSE() {
992 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
993 +        final Condition c = (lock.writeLock().newCondition());
994 +        try {
995 +            lock.getWaitQueueLength(c);
996 +            shouldThrow();
997 +        } catch (IllegalMonitorStateException success) {
998 +        } catch (Exception ex) {
999 +            unexpectedException();
1000 +        }
1001 +    }
1002 +
1003 +
1004 +    /**
1005 +     * getWaitingThreads throws IAE if not owned
1006 +     */
1007 +    public void testGetWaitingThreadsIAE() {
1008 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1009 +        final Condition c = (lock.writeLock().newCondition());
1010 +        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();  
1011 +        try {
1012 +            lock2.getWaitingThreads(c);
1013 +            shouldThrow();
1014 +        } catch (IllegalArgumentException success) {
1015 +        } catch (Exception ex) {
1016 +            unexpectedException();
1017 +        }
1018 +    }
1019 +
1020 +    /**
1021 +     * getWaitingThreads throws IMSE if not locked
1022 +     */
1023 +    public void testGetWaitingThreadsIMSE() {
1024 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1025 +        final Condition c = (lock.writeLock().newCondition());
1026 +        try {
1027 +            lock.getWaitingThreads(c);
1028 +            shouldThrow();
1029 +        } catch (IllegalMonitorStateException success) {
1030 +        } catch (Exception ex) {
1031 +            unexpectedException();
1032 +        }
1033 +    }
1034 +
1035 +
1036 +    /**
1037 +     * hasWaiters returns true when a thread is waiting, else false
1038 +     */
1039 +    public void testHasWaiters() {
1040 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1041 +        final Condition c = (lock.writeLock().newCondition());
1042 +        Thread t = new Thread(new Runnable() {
1043 +                public void run() {
1044 +                    try {
1045 +                        lock.writeLock().lock();
1046 +                        threadAssertFalse(lock.hasWaiters(c));
1047 +                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1048 +                        c.await();
1049 +                        lock.writeLock().unlock();
1050 +                    }
1051 +                    catch(InterruptedException e) {
1052 +                        threadUnexpectedException();
1053 +                    }
1054 +                }
1055 +            });
1056 +
1057 +        try {
1058 +            t.start();
1059 +            Thread.sleep(SHORT_DELAY_MS);
1060 +            lock.writeLock().lock();
1061 +            assertTrue(lock.hasWaiters(c));
1062 +            assertEquals(1, lock.getWaitQueueLength(c));
1063 +            c.signal();
1064 +            lock.writeLock().unlock();
1065 +            Thread.sleep(SHORT_DELAY_MS);
1066 +            lock.writeLock().lock();
1067 +            assertFalse(lock.hasWaiters(c));
1068 +            assertEquals(0, lock.getWaitQueueLength(c));
1069 +            lock.writeLock().unlock();
1070 +            t.join(SHORT_DELAY_MS);
1071 +            assertFalse(t.isAlive());
1072 +        }
1073 +        catch (Exception ex) {
1074 +            unexpectedException();
1075 +        }
1076 +    }
1077 +
1078 +    /**
1079 +     * getWaitQueueLength returns number of waiting threads
1080 +     */
1081 +    public void testGetWaitQueueLength() {
1082 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1083 +        final Condition c = (lock.writeLock().newCondition());
1084 +        Thread t = new Thread(new Runnable() {
1085 +                public void run() {
1086 +                    try {
1087 +                        lock.writeLock().lock();
1088 +                        threadAssertFalse(lock.hasWaiters(c));
1089 +                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1090 +                        c.await();
1091 +                        lock.writeLock().unlock();
1092 +                    }
1093 +                    catch(InterruptedException e) {
1094 +                        threadUnexpectedException();
1095 +                    }
1096 +                }
1097 +            });
1098 +
1099 +        try {
1100 +            t.start();
1101 +            Thread.sleep(SHORT_DELAY_MS);
1102 +            lock.writeLock().lock();
1103 +            assertTrue(lock.hasWaiters(c));
1104 +            assertEquals(1, lock.getWaitQueueLength(c));
1105 +            c.signal();
1106 +            lock.writeLock().unlock();
1107 +            Thread.sleep(SHORT_DELAY_MS);
1108 +            lock.writeLock().lock();
1109 +            assertFalse(lock.hasWaiters(c));
1110 +            assertEquals(0, lock.getWaitQueueLength(c));
1111 +            lock.writeLock().unlock();
1112 +            t.join(SHORT_DELAY_MS);
1113 +            assertFalse(t.isAlive());
1114 +        }
1115 +        catch (Exception ex) {
1116 +            unexpectedException();
1117 +        }
1118 +    }
1119 +
1120 +
1121 +    /**
1122 +     * getWaitingThreads returns only and all waiting threads
1123 +     */
1124 +    public void testGetWaitingThreads() {
1125 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1126 +        final Condition c = lock.writeLock().newCondition();
1127 +        Thread t1 = new Thread(new Runnable() {
1128 +                public void run() {
1129 +                    try {
1130 +                        lock.writeLock().lock();
1131 +                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1132 +                        c.await();
1133 +                        lock.writeLock().unlock();
1134 +                    }
1135 +                    catch(InterruptedException e) {
1136 +                        threadUnexpectedException();
1137 +                    }
1138 +                }
1139 +            });
1140 +
1141 +        Thread t2 = new Thread(new Runnable() {
1142 +                public void run() {
1143 +                    try {
1144 +                        lock.writeLock().lock();
1145 +                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1146 +                        c.await();
1147 +                        lock.writeLock().unlock();
1148 +                    }
1149 +                    catch(InterruptedException e) {
1150 +                        threadUnexpectedException();
1151 +                    }
1152 +                }
1153 +            });
1154 +
1155 +        try {
1156 +            lock.writeLock().lock();
1157 +            assertTrue(lock.getWaitingThreads(c).isEmpty());
1158 +            lock.writeLock().unlock();
1159 +            t1.start();
1160 +            Thread.sleep(SHORT_DELAY_MS);
1161 +            t2.start();
1162 +            Thread.sleep(SHORT_DELAY_MS);
1163 +            lock.writeLock().lock();
1164 +            assertTrue(lock.hasWaiters(c));
1165 +            assertTrue(lock.getWaitingThreads(c).contains(t1));
1166 +            assertTrue(lock.getWaitingThreads(c).contains(t2));
1167 +            c.signalAll();
1168 +            lock.writeLock().unlock();
1169 +            Thread.sleep(SHORT_DELAY_MS);
1170 +            lock.writeLock().lock();
1171 +            assertFalse(lock.hasWaiters(c));
1172 +            assertTrue(lock.getWaitingThreads(c).isEmpty());
1173 +            lock.writeLock().unlock();
1174 +            t1.join(SHORT_DELAY_MS);
1175 +            t2.join(SHORT_DELAY_MS);
1176 +            assertFalse(t1.isAlive());
1177 +            assertFalse(t2.isAlive());
1178 +        }
1179 +        catch (Exception ex) {
1180 +            unexpectedException();
1181 +        }
1182 +    }
1183  
1184   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines