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.11 by dl, Sat Dec 27 18:27:02 2003 UTC

# Line 9 | Line 9 | import junit.framework.*;
9   import java.util.concurrent.locks.*;
10   import java.util.concurrent.*;
11   import java.io.*;
12 + import java.util.*;
13  
14   public class ReentrantReadWriteLockTest extends JSR166TestCase {
15      public static void main(String[] args) {
# Line 18 | Line 19 | public class ReentrantReadWriteLockTest
19          return new TestSuite(ReentrantReadWriteLockTest.class);
20      }
21  
22 +    /**
23 +     * A runnable calling lockInterruptibly
24 +     */
25 +    class InterruptibleLockRunnable implements Runnable {
26 +        final ReentrantReadWriteLock lock;
27 +        InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
28 +        public void run() {
29 +            try {
30 +                lock.writeLock().lockInterruptibly();
31 +            } catch(InterruptedException success){}
32 +        }
33 +    }
34 +
35 +
36 +    /**
37 +     * A runnable calling lockInterruptibly that expects to be
38 +     * interrupted
39 +     */
40 +    class InterruptedLockRunnable implements Runnable {
41 +        final ReentrantReadWriteLock lock;
42 +        InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
43 +        public void run() {
44 +            try {
45 +                lock.writeLock().lockInterruptibly();
46 +                threadShouldThrow();
47 +            } catch(InterruptedException success){}
48 +        }
49 +    }
50 +
51 +    /**
52 +     * Subclass to expose protected methods
53 +     */
54 +    static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
55 +        PublicReentrantReadWriteLock() { super(); }
56 +        public Collection<Thread> getQueuedThreads() {
57 +            return super.getQueuedThreads();
58 +        }
59 +    }
60 +
61 +    /**
62 +     * Constructor sets given fairness, and is in unlocked state
63 +     */
64 +    public void testConstructor() {
65 +        ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
66 +        assertFalse(rl.isFair());
67 +        assertFalse(rl.isWriteLocked());
68 +        assertEquals(0, rl.getReadLockCount());
69 +        ReentrantReadWriteLock r2 = new ReentrantReadWriteLock(true);
70 +        assertTrue(r2.isFair());
71 +        assertFalse(r2.isWriteLocked());
72 +        assertEquals(0, r2.getReadLockCount());
73 +    }
74  
75      /**
76       * write-locking and read-locking an unlocked lock succeed
# Line 25 | Line 78 | public class ReentrantReadWriteLockTest
78      public void testLock() {
79          ReentrantReadWriteLock rl = new ReentrantReadWriteLock();
80          rl.writeLock().lock();
81 +        assertTrue(rl.isWriteLocked());
82 +        assertTrue(rl.isWriteLockedByCurrentThread());
83 +        assertEquals(0, rl.getReadLockCount());
84          rl.writeLock().unlock();
85 +        assertFalse(rl.isWriteLocked());
86 +        assertFalse(rl.isWriteLockedByCurrentThread());
87 +        assertEquals(0, rl.getReadLockCount());
88          rl.readLock().lock();
89 +        assertFalse(rl.isWriteLocked());
90 +        assertFalse(rl.isWriteLockedByCurrentThread());
91 +        assertEquals(1, rl.getReadLockCount());
92          rl.readLock().unlock();
93 +        assertFalse(rl.isWriteLocked());
94 +        assertFalse(rl.isWriteLockedByCurrentThread());
95 +        assertEquals(0, rl.getReadLockCount());
96      }
97  
98  
# Line 37 | Line 102 | public class ReentrantReadWriteLockTest
102      public void testFairLock() {
103          ReentrantReadWriteLock rl = new ReentrantReadWriteLock(true);
104          rl.writeLock().lock();
105 +        assertTrue(rl.isWriteLocked());
106 +        assertTrue(rl.isWriteLockedByCurrentThread());
107 +        assertEquals(0, rl.getReadLockCount());
108          rl.writeLock().unlock();
109 +        assertFalse(rl.isWriteLocked());
110 +        assertFalse(rl.isWriteLockedByCurrentThread());
111 +        assertEquals(0, rl.getReadLockCount());
112          rl.readLock().lock();
113 +        assertFalse(rl.isWriteLocked());
114 +        assertFalse(rl.isWriteLockedByCurrentThread());
115 +        assertEquals(1, rl.getReadLockCount());
116          rl.readLock().unlock();
117 +        assertFalse(rl.isWriteLocked());
118 +        assertFalse(rl.isWriteLockedByCurrentThread());
119 +        assertEquals(0, rl.getReadLockCount());
120      }
121  
122      /**
123 +     * getWriteHoldCount returns number of recursive holds
124 +     */
125 +    public void testGetHoldCount() {
126 +        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
127 +        for(int i = 1; i <= SIZE; i++) {
128 +            lock.writeLock().lock();
129 +            assertEquals(i,lock.getWriteHoldCount());
130 +        }
131 +        for(int i = SIZE; i > 0; i--) {
132 +            lock.writeLock().unlock();
133 +            assertEquals(i-1,lock.getWriteHoldCount());
134 +        }
135 +    }
136 +    
137 +
138 +    /**
139       * write-unlocking an unlocked lock throws IllegalMonitorStateException
140       */
141      public void testUnlock_IllegalMonitorStateException() {
# Line 750 | Line 843 | public class ReentrantReadWriteLockTest
843          }
844      }
845  
846 +    /**
847 +     * getQueueLength reports number of waiting threads
848 +     */
849 +    public void testGetQueueLength() {
850 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
851 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
852 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
853 +        try {
854 +            assertEquals(0, lock.getQueueLength());
855 +            lock.writeLock().lock();
856 +            t1.start();
857 +            Thread.sleep(SHORT_DELAY_MS);
858 +            assertEquals(1, lock.getQueueLength());
859 +            t2.start();
860 +            Thread.sleep(SHORT_DELAY_MS);
861 +            assertEquals(2, lock.getQueueLength());
862 +            t1.interrupt();
863 +            Thread.sleep(SHORT_DELAY_MS);
864 +            assertEquals(1, lock.getQueueLength());
865 +            lock.writeLock().unlock();
866 +            Thread.sleep(SHORT_DELAY_MS);
867 +            assertEquals(0, lock.getQueueLength());
868 +            t1.join();
869 +            t2.join();
870 +        } catch(Exception e){
871 +            unexpectedException();
872 +        }
873 +    }
874 +
875 +    /**
876 +     * getQueuedThreads includes waiting threads
877 +     */
878 +    public void testGetQueuedThreads() {
879 +        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock();
880 +        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
881 +        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
882 +        try {
883 +            assertTrue(lock.getQueuedThreads().isEmpty());
884 +            lock.writeLock().lock();
885 +            assertTrue(lock.getQueuedThreads().isEmpty());
886 +            t1.start();
887 +            Thread.sleep(SHORT_DELAY_MS);
888 +            assertTrue(lock.getQueuedThreads().contains(t1));
889 +            t2.start();
890 +            Thread.sleep(SHORT_DELAY_MS);
891 +            assertTrue(lock.getQueuedThreads().contains(t1));
892 +            assertTrue(lock.getQueuedThreads().contains(t2));
893 +            t1.interrupt();
894 +            Thread.sleep(SHORT_DELAY_MS);
895 +            assertFalse(lock.getQueuedThreads().contains(t1));
896 +            assertTrue(lock.getQueuedThreads().contains(t2));
897 +            lock.writeLock().unlock();
898 +            Thread.sleep(SHORT_DELAY_MS);
899 +            assertTrue(lock.getQueuedThreads().isEmpty());
900 +            t1.join();
901 +            t2.join();
902 +        } catch(Exception e){
903 +            unexpectedException();
904 +        }
905 +    }
906 +
907 +    /**
908 +     * hasWaiters returns true when a thread is waiting, else false
909 +     */
910 +    public void testHasWaiters() {
911 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
912 +        final AbstractQueuedSynchronizer.ConditionObject c = (lock.writeLock().newCondition());
913 +        Thread t = new Thread(new Runnable() {
914 +                public void run() {
915 +                    try {
916 +                        lock.writeLock().lock();
917 +                        threadAssertFalse(c.hasWaiters());
918 +                        threadAssertEquals(0, c.getWaitQueueLength());
919 +                        c.await();
920 +                        lock.writeLock().unlock();
921 +                    }
922 +                    catch(InterruptedException e) {
923 +                        threadUnexpectedException();
924 +                    }
925 +                }
926 +            });
927 +
928 +        try {
929 +            t.start();
930 +            Thread.sleep(SHORT_DELAY_MS);
931 +            lock.writeLock().lock();
932 +            assertTrue(c.hasWaiters());
933 +            assertEquals(1, c.getWaitQueueLength());
934 +            c.signal();
935 +            lock.writeLock().unlock();
936 +            Thread.sleep(SHORT_DELAY_MS);
937 +            lock.writeLock().lock();
938 +            assertFalse(c.hasWaiters());
939 +            assertEquals(0, c.getWaitQueueLength());
940 +            lock.writeLock().unlock();
941 +            t.join(SHORT_DELAY_MS);
942 +            assertFalse(t.isAlive());
943 +        }
944 +        catch (Exception ex) {
945 +            unexpectedException();
946 +        }
947 +    }
948 +
949 +    /**
950 +     * getWaitQueueLength returns number of waiting threads
951 +     */
952 +    public void testGetWaitQueueLength() {
953 +        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();      
954 +        final AbstractQueuedSynchronizer.ConditionObject c = (lock.writeLock().newCondition());
955 +        Thread t1 = new Thread(new Runnable() {
956 +                public void run() {
957 +                    try {
958 +                        lock.writeLock().lock();
959 +                        threadAssertFalse(c.hasWaiters());
960 +                        threadAssertEquals(0, c.getWaitQueueLength());
961 +                        c.await();
962 +                        lock.writeLock().unlock();
963 +                    }
964 +                    catch(InterruptedException e) {
965 +                        threadUnexpectedException();
966 +                    }
967 +                }
968 +            });
969  
970 +        Thread t2 = new Thread(new Runnable() {
971 +                public void run() {
972 +                    try {
973 +                        lock.writeLock().lock();
974 +                        threadAssertTrue(c.hasWaiters());
975 +                        threadAssertEquals(1, c.getWaitQueueLength());
976 +                        c.await();
977 +                        lock.writeLock().unlock();
978 +                    }
979 +                    catch(InterruptedException e) {
980 +                        threadUnexpectedException();
981 +                    }
982 +                }
983 +            });
984 +
985 +        try {
986 +            t1.start();
987 +            Thread.sleep(SHORT_DELAY_MS);
988 +            t2.start();
989 +            Thread.sleep(SHORT_DELAY_MS);
990 +            lock.writeLock().lock();
991 +            assertTrue(c.hasWaiters());
992 +            assertEquals(2, c.getWaitQueueLength());
993 +            c.signalAll();
994 +            lock.writeLock().unlock();
995 +            Thread.sleep(SHORT_DELAY_MS);
996 +            lock.writeLock().lock();
997 +            assertFalse(c.hasWaiters());
998 +            assertEquals(0, c.getWaitQueueLength());
999 +            lock.writeLock().unlock();
1000 +            t1.join(SHORT_DELAY_MS);
1001 +            t2.join(SHORT_DELAY_MS);
1002 +            assertFalse(t1.isAlive());
1003 +            assertFalse(t2.isAlive());
1004 +        }
1005 +        catch (Exception ex) {
1006 +            unexpectedException();
1007 +        }
1008 +    }
1009   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines