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.16 by dl, Wed Jan 7 01:02:17 2004 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 +    /**
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 <    /*
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
144       */
145      public void testUnlock_IllegalMonitorStateException() {
# Line 59 | Line 156 | public class ReentrantReadWriteLockTest
156       */
157      public void testWriteLockInterruptibly_Interrupted() {
158          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
62        lock.writeLock().lock();
159          Thread t = new Thread(new Runnable() {
160                  public void run() {
161                      try {
162                          lock.writeLock().lockInterruptibly();
163 <                        threadShouldThrow();
163 >                        lock.writeLock().unlock();
164 >                        lock.writeLock().lockInterruptibly();
165 >                        lock.writeLock().unlock();
166                      } catch(InterruptedException success){}
167                  }
168              });
169          try {
170 +            lock.writeLock().lock();
171              t.start();
172              t.interrupt();
173              lock.writeLock().unlock();
# Line 79 | Line 178 | public class ReentrantReadWriteLockTest
178      }
179  
180      /**
181 <     * timed write-trylock is interruptible
181 >     * timed write-tryLock is interruptible
182       */
183      public void testWriteTryLock_Interrupted() {
184          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
# Line 112 | Line 211 | public class ReentrantReadWriteLockTest
211                  public void run() {
212                      try {
213                          lock.readLock().lockInterruptibly();
115                        threadShouldThrow();
214                      } catch(InterruptedException success){}
215                  }
216              });
# Line 127 | Line 225 | public class ReentrantReadWriteLockTest
225      }
226  
227      /**
228 <     * timed read-trylock is interruptible
228 >     * timed read-tryLock is interruptible
229       */
230      public void testReadTryLock_Interrupted() {
231          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
# Line 151 | Line 249 | public class ReentrantReadWriteLockTest
249  
250      
251      /**
252 <     * write-trylock fails if locked
252 >     * write-tryLock fails if locked
253       */
254      public void testWriteTryLockWhenLocked() {
255          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
# Line 171 | Line 269 | public class ReentrantReadWriteLockTest
269      }
270  
271      /**
272 <     * read-trylock fails if locked
272 >     * read-tryLock fails if locked
273       */
274      public void testReadTryLockWhenLocked() {
275          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
# Line 281 | Line 379 | public class ReentrantReadWriteLockTest
379  
380  
381      /**
382 <     * Read trylock succeeds if readlocked but not writelocked
382 >     * Read tryLock succeeds if readlocked but not writelocked
383       */
384      public void testTryLockWhenReadLocked() {
385          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
# Line 304 | Line 402 | public class ReentrantReadWriteLockTest
402      
403  
404      /**
405 <     * write trylock fails when readlocked
405 >     * write tryLock fails when readlocked
406       */
407      public void testWriteTryLockWhenReadLocked() {
408          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
# Line 326 | Line 424 | public class ReentrantReadWriteLockTest
424      
425  
426      /**
427 <     * write timed trylock times out if locked
427 >     * write timed tryLock times out if locked
428       */
429      public void testWriteTryLock_Timeout() {
430          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
# Line 350 | Line 448 | public class ReentrantReadWriteLockTest
448      }
449  
450      /**
451 <     * read timed trylock times out if write-locked
451 >     * read timed tryLock times out if write-locked
452       */
453      public void testReadTryLock_Timeout() {
454          final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
# Line 750 | Line 848 | public class ReentrantReadWriteLockTest
848          }
849      }
850  
851 +    /**
852 +     * hasQueuedThreads reports whether there are waiting threads
853 +     */
854 +    public void testhasQueuedThreads() {
855 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
856 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
857 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
858 +        try {
859 +            assertFalse(lock.hasQueuedThreads());
860 +            lock.writeLock().lock();
861 +            t1.start();
862 +            Thread.sleep(SHORT_DELAY_MS);
863 +            assertTrue(lock.hasQueuedThreads());
864 +            t2.start();
865 +            Thread.sleep(SHORT_DELAY_MS);
866 +            assertTrue(lock.hasQueuedThreads());
867 +            t1.interrupt();
868 +            Thread.sleep(SHORT_DELAY_MS);
869 +            assertTrue(lock.hasQueuedThreads());
870 +            lock.writeLock().unlock();
871 +            Thread.sleep(SHORT_DELAY_MS);
872 +            assertFalse(lock.hasQueuedThreads());
873 +            t1.join();
874 +            t2.join();
875 +        } catch(Exception e){
876 +            unexpectedException();
877 +        }
878 +    }
879 +
880 +    /**
881 +     * getQueueLength reports number of waiting threads
882 +     */
883 +    public void testGetQueueLength() {
884 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
885 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
886 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
887 +        try {
888 +            assertEquals(0, lock.getQueueLength());
889 +            lock.writeLock().lock();
890 +            t1.start();
891 +            Thread.sleep(SHORT_DELAY_MS);
892 +            assertEquals(1, lock.getQueueLength());
893 +            t2.start();
894 +            Thread.sleep(SHORT_DELAY_MS);
895 +            assertEquals(2, lock.getQueueLength());
896 +            t1.interrupt();
897 +            Thread.sleep(SHORT_DELAY_MS);
898 +            assertEquals(1, lock.getQueueLength());
899 +            lock.writeLock().unlock();
900 +            Thread.sleep(SHORT_DELAY_MS);
901 +            assertEquals(0, lock.getQueueLength());
902 +            t1.join();
903 +            t2.join();
904 +        } catch(Exception e){
905 +            unexpectedException();
906 +        }
907 +    }
908 +
909 +    /**
910 +     * getQueuedThreads includes waiting threads
911 +     */
912 +    public void testGetQueuedThreads() {
913 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
914 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
915 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
916 +        try {
917 +            assertTrue(lock.getQueuedThreads().isEmpty());
918 +            lock.writeLock().lock();
919 +            assertTrue(lock.getQueuedThreads().isEmpty());
920 +            t1.start();
921 +            Thread.sleep(SHORT_DELAY_MS);
922 +            assertTrue(lock.getQueuedThreads().contains(t1));
923 +            t2.start();
924 +            Thread.sleep(SHORT_DELAY_MS);
925 +            assertTrue(lock.getQueuedThreads().contains(t1));
926 +            assertTrue(lock.getQueuedThreads().contains(t2));
927 +            t1.interrupt();
928 +            Thread.sleep(SHORT_DELAY_MS);
929 +            assertFalse(lock.getQueuedThreads().contains(t1));
930 +            assertTrue(lock.getQueuedThreads().contains(t2));
931 +            lock.writeLock().unlock();
932 +            Thread.sleep(SHORT_DELAY_MS);
933 +            assertTrue(lock.getQueuedThreads().isEmpty());
934 +            t1.join();
935 +            t2.join();
936 +        } catch(Exception e){
937 +            unexpectedException();
938 +        }
939 +    }
940 +
941 +    /**
942 +     * hasWaiters throws NPE if null
943 +     */
944 +    public void testHasWaitersNPE() {
945 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
946 +        try {
947 +            lock.hasWaiters(null);
948 +            shouldThrow();
949 +        } catch (NullPointerException success) {
950 +        } catch (Exception ex) {
951 +            unexpectedException();
952 +        }
953 +    }
954 +
955 +    /**
956 +     * getWaitQueueLength throws NPE if null
957 +     */
958 +    public void testGetWaitQueueLengthNPE() {
959 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
960 +        try {
961 +            lock.getWaitQueueLength(null);
962 +            shouldThrow();
963 +        } catch (NullPointerException success) {
964 +        } catch (Exception ex) {
965 +            unexpectedException();
966 +        }
967 +    }
968 +
969 +
970 +    /**
971 +     * getWaitingThreads throws NPE if null
972 +     */
973 +    public void testGetWaitingThreadsNPE() {
974 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
975 +        try {
976 +            lock.getWaitingThreads(null);
977 +            shouldThrow();
978 +        } catch (NullPointerException success) {
979 +        } catch (Exception ex) {
980 +            unexpectedException();
981 +        }
982 +    }
983 +
984 +    /**
985 +     * hasWaiters throws IAE if not owned
986 +     */
987 +    public void testHasWaitersIAE() {
988 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
989 +        final Condition c = (lock.writeLock().newCondition());
990 +        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
991 +        try {
992 +            lock2.hasWaiters(c);
993 +            shouldThrow();
994 +        } catch (IllegalArgumentException success) {
995 +        } catch (Exception ex) {
996 +            unexpectedException();
997 +        }
998 +    }
999 +
1000 +    /**
1001 +     * hasWaiters throws IMSE if not locked
1002 +     */
1003 +    public void testHasWaitersIMSE() {
1004 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1005 +        final Condition c = (lock.writeLock().newCondition());
1006 +        try {
1007 +            lock.hasWaiters(c);
1008 +            shouldThrow();
1009 +        } catch (IllegalMonitorStateException success) {
1010 +        } catch (Exception ex) {
1011 +            unexpectedException();
1012 +        }
1013 +    }
1014 +
1015 +
1016 +    /**
1017 +     * getWaitQueueLength throws IAE if not owned
1018 +     */
1019 +    public void testGetWaitQueueLengthIAE() {
1020 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1021 +        final Condition c = (lock.writeLock().newCondition());
1022 +        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock();
1023 +        try {
1024 +            lock2.getWaitQueueLength(c);
1025 +            shouldThrow();
1026 +        } catch (IllegalArgumentException success) {
1027 +        } catch (Exception ex) {
1028 +            unexpectedException();
1029 +        }
1030 +    }
1031 +
1032 +    /**
1033 +     * getWaitQueueLength throws IMSE if not locked
1034 +     */
1035 +    public void testGetWaitQueueLengthIMSE() {
1036 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1037 +        final Condition c = (lock.writeLock().newCondition());
1038 +        try {
1039 +            lock.getWaitQueueLength(c);
1040 +            shouldThrow();
1041 +        } catch (IllegalMonitorStateException success) {
1042 +        } catch (Exception ex) {
1043 +            unexpectedException();
1044 +        }
1045 +    }
1046 +
1047 +
1048 +    /**
1049 +     * getWaitingThreads throws IAE if not owned
1050 +     */
1051 +    public void testGetWaitingThreadsIAE() {
1052 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1053 +        final Condition c = (lock.writeLock().newCondition());
1054 +        final PublicReentrantReadWriteLock lock2 = new PublicReentrantReadWriteLock();  
1055 +        try {
1056 +            lock2.getWaitingThreads(c);
1057 +            shouldThrow();
1058 +        } catch (IllegalArgumentException success) {
1059 +        } catch (Exception ex) {
1060 +            unexpectedException();
1061 +        }
1062 +    }
1063 +
1064 +    /**
1065 +     * getWaitingThreads throws IMSE if not locked
1066 +     */
1067 +    public void testGetWaitingThreadsIMSE() {
1068 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1069 +        final Condition c = (lock.writeLock().newCondition());
1070 +        try {
1071 +            lock.getWaitingThreads(c);
1072 +            shouldThrow();
1073 +        } catch (IllegalMonitorStateException success) {
1074 +        } catch (Exception ex) {
1075 +            unexpectedException();
1076 +        }
1077 +    }
1078 +
1079 +
1080 +    /**
1081 +     * hasWaiters returns true when a thread is waiting, else false
1082 +     */
1083 +    public void testHasWaiters() {
1084 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1085 +        final Condition c = (lock.writeLock().newCondition());
1086 +        Thread t = new Thread(new Runnable() {
1087 +                public void run() {
1088 +                    try {
1089 +                        lock.writeLock().lock();
1090 +                        threadAssertFalse(lock.hasWaiters(c));
1091 +                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1092 +                        c.await();
1093 +                        lock.writeLock().unlock();
1094 +                    }
1095 +                    catch(InterruptedException e) {
1096 +                        threadUnexpectedException();
1097 +                    }
1098 +                }
1099 +            });
1100 +
1101 +        try {
1102 +            t.start();
1103 +            Thread.sleep(SHORT_DELAY_MS);
1104 +            lock.writeLock().lock();
1105 +            assertTrue(lock.hasWaiters(c));
1106 +            assertEquals(1, lock.getWaitQueueLength(c));
1107 +            c.signal();
1108 +            lock.writeLock().unlock();
1109 +            Thread.sleep(SHORT_DELAY_MS);
1110 +            lock.writeLock().lock();
1111 +            assertFalse(lock.hasWaiters(c));
1112 +            assertEquals(0, lock.getWaitQueueLength(c));
1113 +            lock.writeLock().unlock();
1114 +            t.join(SHORT_DELAY_MS);
1115 +            assertFalse(t.isAlive());
1116 +        }
1117 +        catch (Exception ex) {
1118 +            unexpectedException();
1119 +        }
1120 +    }
1121 +
1122 +    /**
1123 +     * getWaitQueueLength returns number of waiting threads
1124 +     */
1125 +    public void testGetWaitQueueLength() {
1126 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
1127 +        final Condition c = (lock.writeLock().newCondition());
1128 +        Thread t = new Thread(new Runnable() {
1129 +                public void run() {
1130 +                    try {
1131 +                        lock.writeLock().lock();
1132 +                        threadAssertFalse(lock.hasWaiters(c));
1133 +                        threadAssertEquals(0, lock.getWaitQueueLength(c));
1134 +                        c.await();
1135 +                        lock.writeLock().unlock();
1136 +                    }
1137 +                    catch(InterruptedException e) {
1138 +                        threadUnexpectedException();
1139 +                    }
1140 +                }
1141 +            });
1142 +
1143 +        try {
1144 +            t.start();
1145 +            Thread.sleep(SHORT_DELAY_MS);
1146 +            lock.writeLock().lock();
1147 +            assertTrue(lock.hasWaiters(c));
1148 +            assertEquals(1, lock.getWaitQueueLength(c));
1149 +            c.signal();
1150 +            lock.writeLock().unlock();
1151 +            Thread.sleep(SHORT_DELAY_MS);
1152 +            lock.writeLock().lock();
1153 +            assertFalse(lock.hasWaiters(c));
1154 +            assertEquals(0, lock.getWaitQueueLength(c));
1155 +            lock.writeLock().unlock();
1156 +            t.join(SHORT_DELAY_MS);
1157 +            assertFalse(t.isAlive());
1158 +        }
1159 +        catch (Exception ex) {
1160 +            unexpectedException();
1161 +        }
1162 +    }
1163 +
1164 +
1165 +    /**
1166 +     * getWaitingThreads returns only and all waiting threads
1167 +     */
1168 +    public void testGetWaitingThreads() {
1169 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();  
1170 +        final Condition c = lock.writeLock().newCondition();
1171 +        Thread t1 = new Thread(new Runnable() {
1172 +                public void run() {
1173 +                    try {
1174 +                        lock.writeLock().lock();
1175 +                        threadAssertTrue(lock.getWaitingThreads(c).isEmpty());
1176 +                        c.await();
1177 +                        lock.writeLock().unlock();
1178 +                    }
1179 +                    catch(InterruptedException e) {
1180 +                        threadUnexpectedException();
1181 +                    }
1182 +                }
1183 +            });
1184 +
1185 +        Thread t2 = new Thread(new Runnable() {
1186 +                public void run() {
1187 +                    try {
1188 +                        lock.writeLock().lock();
1189 +                        threadAssertFalse(lock.getWaitingThreads(c).isEmpty());
1190 +                        c.await();
1191 +                        lock.writeLock().unlock();
1192 +                    }
1193 +                    catch(InterruptedException e) {
1194 +                        threadUnexpectedException();
1195 +                    }
1196 +                }
1197 +            });
1198 +
1199 +        try {
1200 +            lock.writeLock().lock();
1201 +            assertTrue(lock.getWaitingThreads(c).isEmpty());
1202 +            lock.writeLock().unlock();
1203 +            t1.start();
1204 +            Thread.sleep(SHORT_DELAY_MS);
1205 +            t2.start();
1206 +            Thread.sleep(SHORT_DELAY_MS);
1207 +            lock.writeLock().lock();
1208 +            assertTrue(lock.hasWaiters(c));
1209 +            assertTrue(lock.getWaitingThreads(c).contains(t1));
1210 +            assertTrue(lock.getWaitingThreads(c).contains(t2));
1211 +            c.signalAll();
1212 +            lock.writeLock().unlock();
1213 +            Thread.sleep(SHORT_DELAY_MS);
1214 +            lock.writeLock().lock();
1215 +            assertFalse(lock.hasWaiters(c));
1216 +            assertTrue(lock.getWaitingThreads(c).isEmpty());
1217 +            lock.writeLock().unlock();
1218 +            t1.join(SHORT_DELAY_MS);
1219 +            t2.join(SHORT_DELAY_MS);
1220 +            assertFalse(t1.isAlive());
1221 +            assertFalse(t2.isAlive());
1222 +        }
1223 +        catch (Exception ex) {
1224 +            unexpectedException();
1225 +        }
1226 +    }
1227  
1228   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines