ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
(Generate patch)

Comparing jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java (file contents):
Revision 1.13 by dl, Fri Jan 9 15:39:10 2004 UTC vs.
Revision 1.41 by jsr166, Sat May 21 06:24:33 2011 UTC

# Line 1 | Line 1
1   /*
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.
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5 > * Other contributors include Andrew Wright, Jeffrey Hayes,
6 > * Pat Fisher, Mike Judd.
7   */
8  
9
9   import junit.framework.*;
10   import java.util.*;
11 < import java.util.concurrent.*;
12 < import java.util.concurrent.locks.*;
13 < import java.io.*;
11 > import static java.util.concurrent.TimeUnit.MILLISECONDS;
12 > import java.util.concurrent.locks.AbstractQueuedSynchronizer;
13 > import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject;
14  
15   public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
16      public static void main(String[] args) {
17 <        junit.textui.TestRunner.run (suite());
17 >        junit.textui.TestRunner.run(suite());
18      }
19      public static Test suite() {
20          return new TestSuite(AbstractQueuedSynchronizerTest.class);
21      }
22  
23      /**
24 <     * A simple mutex class, adapted from the
25 <     * AbstractQueuedSynchronizer javadoc.  Exclusive acquire tests
26 <     * exercise this as a sample user extension.  Other
27 <     * methods/features of AbstractQueuedSynchronizerTest are tested
28 <     * via other test classes, including those for ReentrantLock,
30 <     * ReentrantReadWriteLock, and Semaphore
24 >     * A simple mutex class, adapted from the class javadoc.  Exclusive
25 >     * acquire tests exercise this as a sample user extension.  Other
26 >     * methods/features of AbstractQueuedSynchronizer are tested via
27 >     * other test classes, including those for ReentrantLock,
28 >     * ReentrantReadWriteLock, and Semaphore.
29       */
30      static class Mutex extends AbstractQueuedSynchronizer {
31 <        public boolean isLocked() { return getState() == 1; }
32 <        
33 <        public boolean tryAcquireExclusive(int acquires) {
34 <            assertTrue(acquires == 1);
35 <            return compareAndSetState(0, 1);
36 <        }
37 <        
38 <        public boolean tryReleaseExclusive(int releases) {
39 <            setState(0);
31 >        /** An eccentric value for locked synchronizer state. */
32 >        static final int LOCKED = (1 << 31) | (1 << 15);
33 >
34 >        static final int UNLOCKED = 0;
35 >
36 >        @Override public boolean isHeldExclusively() {
37 >            int state = getState();
38 >            assertTrue(state == UNLOCKED || state == LOCKED);
39 >            return state == LOCKED;
40 >        }
41 >
42 >        @Override public boolean tryAcquire(int acquires) {
43 >            assertEquals(LOCKED, acquires);
44 >            return compareAndSetState(UNLOCKED, LOCKED);
45 >        }
46 >
47 >        @Override public boolean tryRelease(int releases) {
48 >            if (getState() != LOCKED) throw new IllegalMonitorStateException();
49 >            assertEquals(LOCKED, releases);
50 >            setState(UNLOCKED);
51              return true;
52          }
53 <        
54 <        public void checkConditionAccess(Thread thread) {
55 <            if (getState() == 0) throw new IllegalMonitorStateException();
53 >
54 >        public boolean tryAcquireNanos(long nanos) throws InterruptedException {
55 >            return tryAcquireNanos(LOCKED, nanos);
56          }
57 <        
58 <        public ConditionObject newCondition() { return new ConditionObject(); }
59 <        
60 <        public void lock() {
61 <            acquireExclusiveUninterruptibly(1);
57 >
58 >        public boolean tryAcquire() {
59 >            return tryAcquire(LOCKED);
60 >        }
61 >
62 >        public boolean tryRelease() {
63 >            return tryRelease(LOCKED);
64          }
65  
66 +        public void acquire() {
67 +            acquire(LOCKED);
68 +        }
69 +
70 +        public void acquireInterruptibly() throws InterruptedException {
71 +            acquireInterruptibly(LOCKED);
72 +        }
73 +
74 +        public void release() {
75 +            release(LOCKED);
76 +        }
77 +
78 +        public ConditionObject newCondition() {
79 +            return new ConditionObject();
80 +        }
81      }
82  
57    
83      /**
84       * A simple latch class, to test shared mode.
85       */
86 <    static class BooleanLatch extends AbstractQueuedSynchronizer {
86 >    static class BooleanLatch extends AbstractQueuedSynchronizer {
87          public boolean isSignalled() { return getState() != 0; }
88  
89          public int tryAcquireShared(int ignore) {
90 <            return isSignalled()? 1 : -1;
90 >            return isSignalled() ? 1 : -1;
91          }
92 <        
92 >
93          public boolean tryReleaseShared(int ignore) {
94              setState(1);
95              return true;
# Line 72 | Line 97 | public class AbstractQueuedSynchronizerT
97      }
98  
99      /**
100 <     * A runnable calling acquireExclusiveInterruptibly
100 >     * A runnable calling acquireInterruptibly that does not expect to
101 >     * be interrupted.
102       */
103 <    class InterruptibleLockRunnable implements Runnable {
104 <        final Mutex lock;
105 <        InterruptibleLockRunnable(Mutex l) { lock = l; }
106 <        public void run() {
107 <            try {
108 <                lock.acquireExclusiveInterruptibly(1);
109 <            } catch(InterruptedException success){}
103 >    class InterruptibleSyncRunnable extends CheckedRunnable {
104 >        final Mutex sync;
105 >        InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
106 >        public void realRun() throws InterruptedException {
107 >            sync.acquireInterruptibly();
108 >        }
109 >    }
110 >
111 >    /**
112 >     * A runnable calling acquireInterruptibly that expects to be
113 >     * interrupted.
114 >     */
115 >    class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
116 >        final Mutex sync;
117 >        InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
118 >        public void realRun() throws InterruptedException {
119 >            sync.acquireInterruptibly();
120          }
121      }
122  
123 +    /** A constant to clarify calls to checking methods below. */
124 +    final static Thread[] NO_THREADS = new Thread[0];
125  
126      /**
127 <     * A runnable calling acquireExclusiveInterruptibly that expects to be
90 <     * interrupted
127 >     * Spin-waits until sync.isQueued(t) becomes true.
128       */
129 <    class InterruptedLockRunnable implements Runnable {
130 <        final Mutex lock;
131 <        InterruptedLockRunnable(Mutex l) { lock = l; }
132 <        public void run() {
133 <            try {
134 <                lock.acquireExclusiveInterruptibly(1);
98 <                threadShouldThrow();
99 <            } catch(InterruptedException success){}
129 >    void waitForQueuedThread(AbstractQueuedSynchronizer sync, Thread t) {
130 >        long startTime = System.nanoTime();
131 >        while (!sync.isQueued(t)) {
132 >            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
133 >                throw new AssertionFailedError("timed out");
134 >            Thread.yield();
135          }
136 +        assertTrue(t.isAlive());
137      }
138 <    
138 >
139      /**
140 <     * acquireExclusiveUninterruptiblying an releaseExclusiveed lock succeeds
140 >     * Checks that sync has exactly the given queued threads.
141       */
142 <    public void testAcquireExclusiveUninterruptibly() {
143 <        Mutex rl = new Mutex();
144 <        rl.acquireExclusiveUninterruptibly(1);
145 <        assertTrue(rl.isLocked());
146 <        rl.releaseExclusive(1);
142 >    void assertHasQueuedThreads(AbstractQueuedSynchronizer sync,
143 >                                Thread... expected) {
144 >        Collection<Thread> actual = sync.getQueuedThreads();
145 >        assertEquals(expected.length > 0, sync.hasQueuedThreads());
146 >        assertEquals(expected.length, sync.getQueueLength());
147 >        assertEquals(expected.length, actual.size());
148 >        assertEquals(expected.length == 0, actual.isEmpty());
149 >        assertEquals(new HashSet<Thread>(actual),
150 >                     new HashSet<Thread>(Arrays.asList(expected)));
151      }
152  
153      /**
154 <     * tryAcquireExclusive on an releaseExclusiveed lock succeeds
154 >     * Checks that sync has exactly the given (exclusive) queued threads.
155       */
156 <    public void testTryAcquireExclusive() {
157 <        Mutex rl = new Mutex();
158 <        assertTrue(rl.tryAcquireExclusive(1));
159 <        assertTrue(rl.isLocked());
160 <        rl.releaseExclusive(1);
156 >    void assertHasExclusiveQueuedThreads(AbstractQueuedSynchronizer sync,
157 >                                         Thread... expected) {
158 >        assertHasQueuedThreads(sync, expected);
159 >        assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
160 >                     new HashSet<Thread>(sync.getQueuedThreads()));
161 >        assertEquals(0, sync.getSharedQueuedThreads().size());
162 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
163      }
164  
165      /**
166 <     * hasQueuedThreads reports whether there are waiting threads
166 >     * Checks that sync has exactly the given (shared) queued threads.
167       */
168 <    public void testhasQueuedThreads() {
169 <        final Mutex lock = new Mutex();
170 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
171 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
172 <        try {
173 <            assertFalse(lock.hasQueuedThreads());
174 <            lock.acquireExclusiveUninterruptibly(1);
175 <            t1.start();
134 <            Thread.sleep(SHORT_DELAY_MS);
135 <            assertTrue(lock.hasQueuedThreads());
136 <            t2.start();
137 <            Thread.sleep(SHORT_DELAY_MS);
138 <            assertTrue(lock.hasQueuedThreads());
139 <            t1.interrupt();
140 <            Thread.sleep(SHORT_DELAY_MS);
141 <            assertTrue(lock.hasQueuedThreads());
142 <            lock.releaseExclusive(1);
143 <            Thread.sleep(SHORT_DELAY_MS);
144 <            assertFalse(lock.hasQueuedThreads());
145 <            t1.join();
146 <            t2.join();
147 <        } catch(Exception e){
148 <            unexpectedException();
149 <        }
150 <    }
151 <
152 <    /**
153 <     * isQueued(null) throws NPE
154 <     */
155 <    public void testIsQueuedNPE() {
156 <        final Mutex lock = new Mutex();
157 <        try {
158 <            lock.isQueued(null);
159 <            shouldThrow();
160 <        } catch (NullPointerException success) {
161 <        }
162 <    }
163 <
164 <    /**
165 <     * isQueued reports whether a thread is queued.
166 <     */
167 <    public void testIsQueued() {
168 <        final Mutex lock = new Mutex();
169 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
170 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
171 <        try {
172 <            assertFalse(lock.isQueued(t1));
173 <            assertFalse(lock.isQueued(t2));
174 <            lock.acquireExclusiveUninterruptibly(1);
175 <            t1.start();
176 <            Thread.sleep(SHORT_DELAY_MS);
177 <            assertTrue(lock.isQueued(t1));
178 <            t2.start();
179 <            Thread.sleep(SHORT_DELAY_MS);
180 <            assertTrue(lock.isQueued(t1));
181 <            assertTrue(lock.isQueued(t2));
182 <            t1.interrupt();
183 <            Thread.sleep(SHORT_DELAY_MS);
184 <            assertFalse(lock.isQueued(t1));
185 <            assertTrue(lock.isQueued(t2));
186 <            lock.releaseExclusive(1);
187 <            Thread.sleep(SHORT_DELAY_MS);
188 <            assertFalse(lock.isQueued(t1));
189 <            assertFalse(lock.isQueued(t2));
190 <            t1.join();
191 <            t2.join();
192 <        } catch(Exception e){
193 <            unexpectedException();
194 <        }
195 <    }
196 <
197 <    /**
198 <     * getFirstQueuedThread returns first waiting thread or null is none
199 <     */
200 <    public void testGetFirstQueuedThread() {
201 <        final Mutex lock = new Mutex();
202 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
203 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
204 <        try {
205 <            assertNull(lock.getFirstQueuedThread());
206 <            lock.acquireExclusiveUninterruptibly(1);
207 <            t1.start();
208 <            Thread.sleep(SHORT_DELAY_MS);
209 <            assertEquals(t1, lock.getFirstQueuedThread());
210 <            t2.start();
211 <            Thread.sleep(SHORT_DELAY_MS);
212 <            assertEquals(t1, lock.getFirstQueuedThread());
213 <            t1.interrupt();
214 <            Thread.sleep(SHORT_DELAY_MS);
215 <            assertEquals(t2, lock.getFirstQueuedThread());
216 <            lock.releaseExclusive(1);
217 <            Thread.sleep(SHORT_DELAY_MS);
218 <            assertNull(lock.getFirstQueuedThread());
219 <            t1.join();
220 <            t2.join();
221 <        } catch(Exception e){
222 <            unexpectedException();
223 <        }
224 <    }
168 >    void assertHasSharedQueuedThreads(AbstractQueuedSynchronizer sync,
169 >                                      Thread... expected) {
170 >        assertHasQueuedThreads(sync, expected);
171 >        assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
172 >                     new HashSet<Thread>(sync.getQueuedThreads()));
173 >        assertEquals(0, sync.getExclusiveQueuedThreads().size());
174 >        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
175 >    }
176  
177 +    /**
178 +     * Checks that condition c has exactly the given waiter threads,
179 +     * after acquiring mutex.
180 +     */
181 +    void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
182 +                                 Thread... threads) {
183 +        sync.acquire();
184 +        assertHasWaitersLocked(sync, c, threads);
185 +        sync.release();
186 +    }
187  
188      /**
189 <     * hasContended reports false if no thread has ever blocked, else true
189 >     * Checks that condition c has exactly the given waiter threads.
190 >     */
191 >    void assertHasWaitersLocked(Mutex sync, ConditionObject c,
192 >                                Thread... threads) {
193 >        assertEquals(threads.length > 0, sync.hasWaiters(c));
194 >        assertEquals(threads.length, sync.getWaitQueueLength(c));
195 >        assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
196 >        assertEquals(threads.length, sync.getWaitingThreads(c).size());
197 >        assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
198 >                     new HashSet<Thread>(Arrays.asList(threads)));
199 >    }
200 >
201 >    enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
202 >
203 >    /**
204 >     * Awaits condition using the specified AwaitMethod.
205       */
206 <    public void testHasContended() {
207 <        final Mutex lock = new Mutex();
208 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
209 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
210 <        try {
211 <            assertFalse(lock.hasContended());
212 <            lock.acquireExclusiveUninterruptibly(1);
213 <            t1.start();
214 <            Thread.sleep(SHORT_DELAY_MS);
215 <            assertTrue(lock.hasContended());
216 <            t2.start();
217 <            Thread.sleep(SHORT_DELAY_MS);
218 <            assertTrue(lock.hasContended());
219 <            t1.interrupt();
220 <            Thread.sleep(SHORT_DELAY_MS);
221 <            assertTrue(lock.hasContended());
222 <            lock.releaseExclusive(1);
223 <            Thread.sleep(SHORT_DELAY_MS);
248 <            assertTrue(lock.hasContended());
249 <            t1.join();
250 <            t2.join();
251 <        } catch(Exception e){
252 <            unexpectedException();
253 <        }
254 <    }
255 <
256 <    /**
257 <     * acquireExclusiveNanos is interruptible.
258 <     */
259 <    public void testInterruptedException2() {
260 <        final Mutex lock = new Mutex();
261 <        lock.acquireExclusiveUninterruptibly(1);
262 <        Thread t = new Thread(new Runnable() {
263 <                public void run() {
264 <                    try {
265 <                        lock.acquireExclusiveNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
266 <                        threadShouldThrow();
267 <                    } catch(InterruptedException success){}
268 <                }
269 <            });
270 <        try {
271 <            t.start();
272 <            t.interrupt();
273 <        } catch(Exception e){
274 <            unexpectedException();
206 >    void await(ConditionObject c, AwaitMethod awaitMethod)
207 >            throws InterruptedException {
208 >        long timeoutMillis = 2 * LONG_DELAY_MS;
209 >        switch (awaitMethod) {
210 >        case await:
211 >            c.await();
212 >            break;
213 >        case awaitTimed:
214 >            assertTrue(c.await(timeoutMillis, MILLISECONDS));
215 >            break;
216 >        case awaitNanos:
217 >            long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
218 >            long nanosRemaining = c.awaitNanos(nanosTimeout);
219 >            assertTrue(nanosRemaining > 0);
220 >            break;
221 >        case awaitUntil:
222 >            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
223 >            break;
224          }
225      }
226  
227 +    /**
228 +     * Checks that awaiting the given condition times out (using the
229 +     * default timeout duration).
230 +     */
231 +    void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
232 +        long timeoutMillis = timeoutMillis();
233 +        long startTime = System.nanoTime();
234 +        try {
235 +            switch (awaitMethod) {
236 +            case awaitTimed:
237 +                assertFalse(c.await(timeoutMillis, MILLISECONDS));
238 +                break;
239 +            case awaitNanos:
240 +                long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
241 +                long nanosRemaining = c.awaitNanos(nanosTimeout);
242 +                assertTrue(nanosRemaining <= 0);
243 +                break;
244 +            case awaitUntil:
245 +                assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
246 +                break;
247 +            default:
248 +                throw new UnsupportedOperationException();
249 +            }
250 +        } catch (InterruptedException ie) { threadUnexpectedException(ie); }
251 +        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
252 +    }
253 +
254 +    /**
255 +     * isHeldExclusively is false upon construction
256 +     */
257 +    public void testIsHeldExclusively() {
258 +        Mutex sync = new Mutex();
259 +        assertFalse(sync.isHeldExclusively());
260 +    }
261 +
262 +    /**
263 +     * acquiring released sync succeeds
264 +     */
265 +    public void testAcquire() {
266 +        Mutex sync = new Mutex();
267 +        sync.acquire();
268 +        assertTrue(sync.isHeldExclusively());
269 +        sync.release();
270 +        assertFalse(sync.isHeldExclusively());
271 +    }
272 +
273 +    /**
274 +     * tryAcquire on a released sync succeeds
275 +     */
276 +    public void testTryAcquire() {
277 +        Mutex sync = new Mutex();
278 +        assertTrue(sync.tryAcquire());
279 +        assertTrue(sync.isHeldExclusively());
280 +        sync.release();
281 +        assertFalse(sync.isHeldExclusively());
282 +    }
283 +
284 +    /**
285 +     * hasQueuedThreads reports whether there are waiting threads
286 +     */
287 +    public void testHasQueuedThreads() {
288 +        final Mutex sync = new Mutex();
289 +        assertFalse(sync.hasQueuedThreads());
290 +        sync.acquire();
291 +        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
292 +        waitForQueuedThread(sync, t1);
293 +        assertTrue(sync.hasQueuedThreads());
294 +        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
295 +        waitForQueuedThread(sync, t2);
296 +        assertTrue(sync.hasQueuedThreads());
297 +        t1.interrupt();
298 +        awaitTermination(t1);
299 +        assertTrue(sync.hasQueuedThreads());
300 +        sync.release();
301 +        awaitTermination(t2);
302 +        assertFalse(sync.hasQueuedThreads());
303 +    }
304 +
305 +    /**
306 +     * isQueued(null) throws NullPointerException
307 +     */
308 +    public void testIsQueuedNPE() {
309 +        final Mutex sync = new Mutex();
310 +        try {
311 +            sync.isQueued(null);
312 +            shouldThrow();
313 +        } catch (NullPointerException success) {}
314 +    }
315 +
316 +    /**
317 +     * isQueued reports whether a thread is queued
318 +     */
319 +    public void testIsQueued() {
320 +        final Mutex sync = new Mutex();
321 +        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
322 +        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
323 +        assertFalse(sync.isQueued(t1));
324 +        assertFalse(sync.isQueued(t2));
325 +        sync.acquire();
326 +        t1.start();
327 +        waitForQueuedThread(sync, t1);
328 +        assertTrue(sync.isQueued(t1));
329 +        assertFalse(sync.isQueued(t2));
330 +        t2.start();
331 +        waitForQueuedThread(sync, t2);
332 +        assertTrue(sync.isQueued(t1));
333 +        assertTrue(sync.isQueued(t2));
334 +        t1.interrupt();
335 +        awaitTermination(t1);
336 +        assertFalse(sync.isQueued(t1));
337 +        assertTrue(sync.isQueued(t2));
338 +        sync.release();
339 +        awaitTermination(t2);
340 +        assertFalse(sync.isQueued(t1));
341 +        assertFalse(sync.isQueued(t2));
342 +    }
343  
344      /**
345 <     * TryAcquireExclusive on a locked lock fails
346 <     */
347 <    public void testTryAcquireExclusiveWhenLocked() {
348 <        final Mutex lock = new Mutex();
349 <        lock.acquireExclusiveUninterruptibly(1);
350 <        Thread t = new Thread(new Runnable() {
351 <                public void run() {
352 <                    threadAssertFalse(lock.tryAcquireExclusive(1));
353 <                }
354 <            });
355 <        try {
356 <            t.start();
357 <            t.join();
358 <            lock.releaseExclusive(1);
359 <        } catch(Exception e){
360 <            unexpectedException();
361 <        }
362 <    }
363 <
364 <    /**
365 <     * acquireExclusiveNanos on a locked lock times out
366 <     */
367 <    public void testAcquireExclusiveNanos_Timeout() {
368 <        final Mutex lock = new Mutex();
369 <        lock.acquireExclusiveUninterruptibly(1);
370 <        Thread t = new Thread(new Runnable() {
371 <                public void run() {
372 <                    try {
373 <                        threadAssertFalse(lock.acquireExclusiveNanos(1, 1000 * 1000));
374 <                    } catch (Exception ex) {
375 <                        threadUnexpectedException();
376 <                    }
377 <                }
378 <            });
379 <        try {
380 <            t.start();
381 <            t.join();
382 <            lock.releaseExclusive(1);
383 <        } catch(Exception e){
384 <            unexpectedException();
385 <        }
386 <    }
387 <    
388 <  
345 >     * getFirstQueuedThread returns first waiting thread or null if none
346 >     */
347 >    public void testGetFirstQueuedThread() {
348 >        final Mutex sync = new Mutex();
349 >        assertNull(sync.getFirstQueuedThread());
350 >        sync.acquire();
351 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
352 >        waitForQueuedThread(sync, t1);
353 >        assertEquals(t1, sync.getFirstQueuedThread());
354 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
355 >        waitForQueuedThread(sync, t2);
356 >        assertEquals(t1, sync.getFirstQueuedThread());
357 >        t1.interrupt();
358 >        awaitTermination(t1);
359 >        assertEquals(t2, sync.getFirstQueuedThread());
360 >        sync.release();
361 >        awaitTermination(t2);
362 >        assertNull(sync.getFirstQueuedThread());
363 >    }
364 >
365 >    /**
366 >     * hasContended reports false if no thread has ever blocked, else true
367 >     */
368 >    public void testHasContended() {
369 >        final Mutex sync = new Mutex();
370 >        assertFalse(sync.hasContended());
371 >        sync.acquire();
372 >        assertFalse(sync.hasContended());
373 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
374 >        waitForQueuedThread(sync, t1);
375 >        assertTrue(sync.hasContended());
376 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
377 >        waitForQueuedThread(sync, t2);
378 >        assertTrue(sync.hasContended());
379 >        t1.interrupt();
380 >        awaitTermination(t1);
381 >        assertTrue(sync.hasContended());
382 >        sync.release();
383 >        awaitTermination(t2);
384 >        assertTrue(sync.hasContended());
385 >    }
386 >
387 >    /**
388 >     * getQueuedThreads returns all waiting threads
389 >     */
390 >    public void testGetQueuedThreads() {
391 >        final Mutex sync = new Mutex();
392 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
393 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
394 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
395 >        sync.acquire();
396 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
397 >        t1.start();
398 >        waitForQueuedThread(sync, t1);
399 >        assertHasExclusiveQueuedThreads(sync, t1);
400 >        assertTrue(sync.getQueuedThreads().contains(t1));
401 >        assertFalse(sync.getQueuedThreads().contains(t2));
402 >        t2.start();
403 >        waitForQueuedThread(sync, t2);
404 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
405 >        assertTrue(sync.getQueuedThreads().contains(t1));
406 >        assertTrue(sync.getQueuedThreads().contains(t2));
407 >        t1.interrupt();
408 >        awaitTermination(t1);
409 >        assertHasExclusiveQueuedThreads(sync, t2);
410 >        sync.release();
411 >        awaitTermination(t2);
412 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
413 >    }
414 >
415 >    /**
416 >     * getExclusiveQueuedThreads returns all exclusive waiting threads
417 >     */
418 >    public void testGetExclusiveQueuedThreads() {
419 >        final Mutex sync = new Mutex();
420 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
421 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
422 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
423 >        sync.acquire();
424 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
425 >        t1.start();
426 >        waitForQueuedThread(sync, t1);
427 >        assertHasExclusiveQueuedThreads(sync, t1);
428 >        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
429 >        assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
430 >        t2.start();
431 >        waitForQueuedThread(sync, t2);
432 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
433 >        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
434 >        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
435 >        t1.interrupt();
436 >        awaitTermination(t1);
437 >        assertHasExclusiveQueuedThreads(sync, t2);
438 >        sync.release();
439 >        awaitTermination(t2);
440 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
441 >    }
442 >
443 >    /**
444 >     * getSharedQueuedThreads does not include exclusively waiting threads
445 >     */
446 >    public void testGetSharedQueuedThreads_Exclusive() {
447 >        final Mutex sync = new Mutex();
448 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
449 >        sync.acquire();
450 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
451 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
452 >        waitForQueuedThread(sync, t1);
453 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
454 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
455 >        waitForQueuedThread(sync, t2);
456 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
457 >        t1.interrupt();
458 >        awaitTermination(t1);
459 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
460 >        sync.release();
461 >        awaitTermination(t2);
462 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
463 >    }
464 >
465 >    /**
466 >     * getSharedQueuedThreads returns all shared waiting threads
467 >     */
468 >    public void testGetSharedQueuedThreads_Shared() {
469 >        final BooleanLatch l = new BooleanLatch();
470 >        assertHasSharedQueuedThreads(l, NO_THREADS);
471 >        Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
472 >            public void realRun() throws InterruptedException {
473 >                l.acquireSharedInterruptibly(0);
474 >            }});
475 >        waitForQueuedThread(l, t1);
476 >        assertHasSharedQueuedThreads(l, t1);
477 >        Thread t2 = newStartedThread(new CheckedRunnable() {
478 >            public void realRun() throws InterruptedException {
479 >                l.acquireSharedInterruptibly(0);
480 >            }});
481 >        waitForQueuedThread(l, t2);
482 >        assertHasSharedQueuedThreads(l, t1, t2);
483 >        t1.interrupt();
484 >        awaitTermination(t1);
485 >        assertHasSharedQueuedThreads(l, t2);
486 >        assertTrue(l.releaseShared(0));
487 >        awaitTermination(t2);
488 >        assertHasSharedQueuedThreads(l, NO_THREADS);
489 >    }
490 >
491 >    /**
492 >     * tryAcquireNanos is interruptible
493 >     */
494 >    public void testTryAcquireNanos_Interruptible() {
495 >        final Mutex sync = new Mutex();
496 >        sync.acquire();
497 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
498 >            public void realRun() throws InterruptedException {
499 >                sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
500 >            }});
501 >
502 >        waitForQueuedThread(sync, t);
503 >        t.interrupt();
504 >        awaitTermination(t);
505 >    }
506 >
507 >    /**
508 >     * tryAcquire on exclusively held sync fails
509 >     */
510 >    public void testTryAcquireWhenSynced() {
511 >        final Mutex sync = new Mutex();
512 >        sync.acquire();
513 >        Thread t = newStartedThread(new CheckedRunnable() {
514 >            public void realRun() {
515 >                assertFalse(sync.tryAcquire());
516 >            }});
517 >
518 >        awaitTermination(t);
519 >        sync.release();
520 >    }
521 >
522 >    /**
523 >     * tryAcquireNanos on an exclusively held sync times out
524 >     */
525 >    public void testAcquireNanos_Timeout() {
526 >        final Mutex sync = new Mutex();
527 >        sync.acquire();
528 >        Thread t = newStartedThread(new CheckedRunnable() {
529 >            public void realRun() throws InterruptedException {
530 >                long startTime = System.nanoTime();
531 >                long nanos = MILLISECONDS.toNanos(timeoutMillis());
532 >                assertFalse(sync.tryAcquireNanos(nanos));
533 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
534 >            }});
535 >
536 >        awaitTermination(t);
537 >        sync.release();
538 >    }
539 >
540      /**
541       * getState is true when acquired and false when not
542       */
543      public void testGetState() {
544 <        final Mutex lock = new Mutex();
545 <        lock.acquireExclusiveUninterruptibly(1);
546 <        assertTrue(lock.isLocked());
547 <        lock.releaseExclusive(1);
548 <        assertFalse(lock.isLocked());
549 <        Thread t = new Thread(new Runnable() {
550 <                public void run() {
551 <                    lock.acquireExclusiveUninterruptibly(1);
552 <                    try {
553 <                        Thread.sleep(SMALL_DELAY_MS);
554 <                    }
555 <                    catch(Exception e) {
556 <                        threadUnexpectedException();
557 <                    }
558 <                    lock.releaseExclusive(1);
559 <                }
560 <            });
561 <        try {
562 <            t.start();
563 <            Thread.sleep(SHORT_DELAY_MS);
564 <            assertTrue(lock.isLocked());
349 <            t.join();
350 <            assertFalse(lock.isLocked());
351 <        } catch(Exception e){
352 <            unexpectedException();
353 <        }
544 >        final Mutex sync = new Mutex();
545 >        sync.acquire();
546 >        assertTrue(sync.isHeldExclusively());
547 >        sync.release();
548 >        assertFalse(sync.isHeldExclusively());
549 >
550 >        final BooleanLatch acquired = new BooleanLatch();
551 >        final BooleanLatch done = new BooleanLatch();
552 >        Thread t = newStartedThread(new CheckedRunnable() {
553 >            public void realRun() throws InterruptedException {
554 >                sync.acquire();
555 >                assertTrue(acquired.releaseShared(0));
556 >                done.acquireShared(0);
557 >                sync.release();
558 >            }});
559 >
560 >        acquired.acquireShared(0);
561 >        assertTrue(sync.isHeldExclusively());
562 >        assertTrue(done.releaseShared(0));
563 >        awaitTermination(t);
564 >        assertFalse(sync.isHeldExclusively());
565      }
566  
567 +    /**
568 +     * acquireInterruptibly succeeds when released, else is interruptible
569 +     */
570 +    public void testAcquireInterruptibly() throws InterruptedException {
571 +        final Mutex sync = new Mutex();
572 +        final BooleanLatch threadStarted = new BooleanLatch();
573 +        sync.acquireInterruptibly();
574 +        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
575 +            public void realRun() throws InterruptedException {
576 +                assertTrue(threadStarted.releaseShared(0));
577 +                sync.acquireInterruptibly();
578 +            }});
579 +
580 +        threadStarted.acquireShared(0);
581 +        waitForQueuedThread(sync, t);
582 +        t.interrupt();
583 +        awaitTermination(t);
584 +        assertTrue(sync.isHeldExclusively());
585 +    }
586  
587      /**
588 <     * acquireExclusiveInterruptibly is interruptible.
589 <     */
590 <    public void testAcquireInterruptibly1() {
591 <        final Mutex lock = new Mutex();
592 <        lock.acquireExclusiveUninterruptibly(1);
593 <        Thread t = new Thread(new InterruptedLockRunnable(lock));
594 <        try {
595 <            t.start();
596 <            t.interrupt();
597 <            lock.releaseExclusive(1);
598 <            t.join();
599 <        } catch(Exception e){
600 <            unexpectedException();
601 <        }
602 <    }
603 <
604 <    /**
605 <     * acquireExclusiveInterruptibly succeeds when released, else is interruptible
606 <     */
607 <    public void testAcquireInterruptibly2() {
608 <        final Mutex lock = new Mutex();
609 <        try {
610 <            lock.acquireExclusiveInterruptibly(1);
611 <        } catch(Exception e) {
382 <            unexpectedException();
383 <        }
384 <        Thread t = new Thread(new InterruptedLockRunnable(lock));
385 <        try {
386 <            t.start();
387 <            t.interrupt();
388 <            assertTrue(lock.isLocked());
389 <            t.join();
390 <        } catch(Exception e){
391 <            unexpectedException();
588 >     * owns is true for a condition created by sync else false
589 >     */
590 >    public void testOwns() {
591 >        final Mutex sync = new Mutex();
592 >        final ConditionObject c = sync.newCondition();
593 >        final Mutex sync2 = new Mutex();
594 >        assertTrue(sync.owns(c));
595 >        assertFalse(sync2.owns(c));
596 >    }
597 >
598 >    /**
599 >     * Calling await without holding sync throws IllegalMonitorStateException
600 >     */
601 >    public void testAwait_IMSE() {
602 >        final Mutex sync = new Mutex();
603 >        final ConditionObject c = sync.newCondition();
604 >        for (AwaitMethod awaitMethod : AwaitMethod.values()) {
605 >            long startTime = System.nanoTime();
606 >            try {
607 >                await(c, awaitMethod);
608 >                shouldThrow();
609 >            } catch (IllegalMonitorStateException success) {
610 >            } catch (InterruptedException e) { threadUnexpectedException(e); }
611 >            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
612          }
613      }
614  
615      /**
616 <     * owns is true for a condition created by lock else false
616 >     * Calling signal without holding sync throws IllegalMonitorStateException
617       */
618 <    public void testOwns() {
619 <        final Mutex lock = new Mutex();
620 <        final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
621 <        final Mutex lock2 = new Mutex();
622 <        assertTrue(lock.owns(c));
623 <        assertFalse(lock2.owns(c));
618 >    public void testSignal_IMSE() {
619 >        final Mutex sync = new Mutex();
620 >        final ConditionObject c = sync.newCondition();
621 >        try {
622 >            c.signal();
623 >            shouldThrow();
624 >        } catch (IllegalMonitorStateException success) {}
625 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
626      }
627  
628      /**
629 <     * Calling await without holding lock throws IllegalMonitorStateException
629 >     * Calling signalAll without holding sync throws IllegalMonitorStateException
630       */
631 <    public void testAwait_IllegalMonitor() {
632 <        final Mutex lock = new Mutex();
633 <        final Condition c = lock.newCondition();
631 >    public void testSignalAll_IMSE() {
632 >        final Mutex sync = new Mutex();
633 >        final ConditionObject c = sync.newCondition();
634          try {
635 <            c.await();
635 >            c.signalAll();
636              shouldThrow();
637 <        }
638 <        catch (IllegalMonitorStateException success) {
639 <        }
640 <        catch (Exception ex) {
641 <            unexpectedException();
642 <        }
637 >        } catch (IllegalMonitorStateException success) {}
638 >    }
639 >
640 >    /**
641 >     * await/awaitNanos/awaitUntil without a signal times out
642 >     */
643 >    public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
644 >    public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
645 >    public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
646 >    public void testAwait_Timeout(AwaitMethod awaitMethod) {
647 >        final Mutex sync = new Mutex();
648 >        final ConditionObject c = sync.newCondition();
649 >        sync.acquire();
650 >        assertAwaitTimesOut(c, awaitMethod);
651 >        sync.release();
652      }
653  
654      /**
655 <     * Calling signal without holding lock throws IllegalMonitorStateException
655 >     * await/awaitNanos/awaitUntil returns when signalled
656 >     */
657 >    public void testSignal_await()      { testSignal(AwaitMethod.await); }
658 >    public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
659 >    public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
660 >    public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
661 >    public void testSignal(final AwaitMethod awaitMethod) {
662 >        final Mutex sync = new Mutex();
663 >        final ConditionObject c = sync.newCondition();
664 >        final BooleanLatch acquired = new BooleanLatch();
665 >        Thread t = newStartedThread(new CheckedRunnable() {
666 >            public void realRun() throws InterruptedException {
667 >                sync.acquire();
668 >                assertTrue(acquired.releaseShared(0));
669 >                await(c, awaitMethod);
670 >                sync.release();
671 >            }});
672 >
673 >        acquired.acquireShared(0);
674 >        sync.acquire();
675 >        assertHasWaitersLocked(sync, c, t);
676 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
677 >        c.signal();
678 >        assertHasWaitersLocked(sync, c, NO_THREADS);
679 >        assertHasExclusiveQueuedThreads(sync, t);
680 >        sync.release();
681 >        awaitTermination(t);
682 >    }
683 >
684 >    /**
685 >     * hasWaiters(null) throws NullPointerException
686       */
687 <    public void testSignal_IllegalMonitor() {
688 <        final Mutex lock = new Mutex();
428 <        final Condition c = lock.newCondition();
687 >    public void testHasWaitersNPE() {
688 >        final Mutex sync = new Mutex();
689          try {
690 <            c.signal();
690 >            sync.hasWaiters(null);
691              shouldThrow();
692 <        }
433 <        catch (IllegalMonitorStateException success) {
434 <        }
435 <        catch (Exception ex) {
436 <            unexpectedException();
437 <        }
692 >        } catch (NullPointerException success) {}
693      }
694  
695      /**
696 <     * awaitNanos without a signal times out
696 >     * getWaitQueueLength(null) throws NullPointerException
697       */
698 <    public void testAwaitNanos_Timeout() {
699 <        final Mutex lock = new Mutex();
445 <        final Condition c = lock.newCondition();
698 >    public void testGetWaitQueueLengthNPE() {
699 >        final Mutex sync = new Mutex();
700          try {
701 <            lock.acquireExclusiveUninterruptibly(1);
702 <            long t = c.awaitNanos(100);
703 <            assertTrue(t <= 0);
450 <            lock.releaseExclusive(1);
451 <        }
452 <        catch (Exception ex) {
453 <            unexpectedException();
454 <        }
701 >            sync.getWaitQueueLength(null);
702 >            shouldThrow();
703 >        } catch (NullPointerException success) {}
704      }
705  
706      /**
707 <     *  timed await without a signal times out
707 >     * getWaitingThreads(null) throws NullPointerException
708       */
709 <    public void testAwait_Timeout() {
710 <        final Mutex lock = new Mutex();
462 <        final Condition c = lock.newCondition();
709 >    public void testGetWaitingThreadsNPE() {
710 >        final Mutex sync = new Mutex();
711          try {
712 <            lock.acquireExclusiveUninterruptibly(1);
713 <            assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
714 <            lock.releaseExclusive(1);
467 <        }
468 <        catch (Exception ex) {
469 <            unexpectedException();
470 <        }
712 >            sync.getWaitingThreads(null);
713 >            shouldThrow();
714 >        } catch (NullPointerException success) {}
715      }
716  
717      /**
718 <     * awaitUntil without a signal times out
718 >     * hasWaiters throws IllegalArgumentException if not owned
719       */
720 <    public void testAwaitUntil_Timeout() {
721 <        final Mutex lock = new Mutex();
722 <        final Condition c = lock.newCondition();
720 >    public void testHasWaitersIAE() {
721 >        final Mutex sync = new Mutex();
722 >        final ConditionObject c = sync.newCondition();
723 >        final Mutex sync2 = new Mutex();
724          try {
725 <            lock.acquireExclusiveUninterruptibly(1);
726 <            java.util.Date d = new java.util.Date();
727 <            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
728 <            lock.releaseExclusive(1);
729 <        }
730 <        catch (Exception ex) {
731 <            unexpectedException();
732 <        }
725 >            sync2.hasWaiters(c);
726 >            shouldThrow();
727 >        } catch (IllegalArgumentException success) {}
728 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
729 >    }
730 >
731 >    /**
732 >     * hasWaiters throws IllegalMonitorStateException if not synced
733 >     */
734 >    public void testHasWaitersIMSE() {
735 >        final Mutex sync = new Mutex();
736 >        final ConditionObject c = sync.newCondition();
737 >        try {
738 >            sync.hasWaiters(c);
739 >            shouldThrow();
740 >        } catch (IllegalMonitorStateException success) {}
741 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
742      }
743  
744      /**
745 <     * await returns when signalled
745 >     * getWaitQueueLength throws IllegalArgumentException if not owned
746       */
747 <    public void testAwait() {
748 <        final Mutex lock = new Mutex();
749 <        final Condition c = lock.newCondition();
750 <        Thread t = new Thread(new Runnable() {
751 <                public void run() {
752 <                    try {
753 <                        lock.acquireExclusiveUninterruptibly(1);
754 <                        c.await();
755 <                        lock.releaseExclusive(1);
756 <                    }
503 <                    catch(InterruptedException e) {
504 <                        threadUnexpectedException();
505 <                    }
506 <                }
507 <            });
747 >    public void testGetWaitQueueLengthIAE() {
748 >        final Mutex sync = new Mutex();
749 >        final ConditionObject c = sync.newCondition();
750 >        final Mutex sync2 = new Mutex();
751 >        try {
752 >            sync2.getWaitQueueLength(c);
753 >            shouldThrow();
754 >        } catch (IllegalArgumentException success) {}
755 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
756 >    }
757  
758 +    /**
759 +     * getWaitQueueLength throws IllegalMonitorStateException if not synced
760 +     */
761 +    public void testGetWaitQueueLengthIMSE() {
762 +        final Mutex sync = new Mutex();
763 +        final ConditionObject c = sync.newCondition();
764          try {
765 <            t.start();
766 <            Thread.sleep(SHORT_DELAY_MS);
767 <            lock.acquireExclusiveUninterruptibly(1);
768 <            c.signal();
769 <            lock.releaseExclusive(1);
770 <            t.join(SHORT_DELAY_MS);
771 <            assertFalse(t.isAlive());
772 <        }
773 <        catch (Exception ex) {
774 <            unexpectedException();
775 <        }
765 >            sync.getWaitQueueLength(c);
766 >            shouldThrow();
767 >        } catch (IllegalMonitorStateException success) {}
768 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
769 >    }
770 >
771 >    /**
772 >     * getWaitingThreads throws IllegalArgumentException if not owned
773 >     */
774 >    public void testGetWaitingThreadsIAE() {
775 >        final Mutex sync = new Mutex();
776 >        final ConditionObject c = sync.newCondition();
777 >        final Mutex sync2 = new Mutex();
778 >        try {
779 >            sync2.getWaitingThreads(c);
780 >            shouldThrow();
781 >        } catch (IllegalArgumentException success) {}
782 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
783 >    }
784 >
785 >    /**
786 >     * getWaitingThreads throws IllegalMonitorStateException if not synced
787 >     */
788 >    public void testGetWaitingThreadsIMSE() {
789 >        final Mutex sync = new Mutex();
790 >        final ConditionObject c = sync.newCondition();
791 >        try {
792 >            sync.getWaitingThreads(c);
793 >            shouldThrow();
794 >        } catch (IllegalMonitorStateException success) {}
795 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
796      }
797  
798 +    /**
799 +     * hasWaiters returns true when a thread is waiting, else false
800 +     */
801 +    public void testHasWaiters() {
802 +        final Mutex sync = new Mutex();
803 +        final ConditionObject c = sync.newCondition();
804 +        final BooleanLatch acquired = new BooleanLatch();
805 +        Thread t = newStartedThread(new CheckedRunnable() {
806 +            public void realRun() throws InterruptedException {
807 +                sync.acquire();
808 +                assertHasWaitersLocked(sync, c, NO_THREADS);
809 +                assertFalse(sync.hasWaiters(c));
810 +                assertTrue(acquired.releaseShared(0));
811 +                c.await();
812 +                sync.release();
813 +            }});
814 +
815 +        acquired.acquireShared(0);
816 +        sync.acquire();
817 +        assertHasWaitersLocked(sync, c, t);
818 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
819 +        assertTrue(sync.hasWaiters(c));
820 +        c.signal();
821 +        assertHasWaitersLocked(sync, c, NO_THREADS);
822 +        assertHasExclusiveQueuedThreads(sync, t);
823 +        assertFalse(sync.hasWaiters(c));
824 +        sync.release();
825 +
826 +        awaitTermination(t);
827 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
828 +    }
829 +
830 +    /**
831 +     * getWaitQueueLength returns number of waiting threads
832 +     */
833 +    public void testGetWaitQueueLength() {
834 +        final Mutex sync = new Mutex();
835 +        final ConditionObject c = sync.newCondition();
836 +        final BooleanLatch acquired1 = new BooleanLatch();
837 +        final BooleanLatch acquired2 = new BooleanLatch();
838 +        final Thread t1 = newStartedThread(new CheckedRunnable() {
839 +            public void realRun() throws InterruptedException {
840 +                sync.acquire();
841 +                assertHasWaitersLocked(sync, c, NO_THREADS);
842 +                assertEquals(0, sync.getWaitQueueLength(c));
843 +                assertTrue(acquired1.releaseShared(0));
844 +                c.await();
845 +                sync.release();
846 +            }});
847 +        acquired1.acquireShared(0);
848 +        sync.acquire();
849 +        assertHasWaitersLocked(sync, c, t1);
850 +        assertEquals(1, sync.getWaitQueueLength(c));
851 +        sync.release();
852 +
853 +        final Thread t2 = newStartedThread(new CheckedRunnable() {
854 +            public void realRun() throws InterruptedException {
855 +                sync.acquire();
856 +                assertHasWaitersLocked(sync, c, t1);
857 +                assertEquals(1, sync.getWaitQueueLength(c));
858 +                assertTrue(acquired2.releaseShared(0));
859 +                c.await();
860 +                sync.release();
861 +            }});
862 +        acquired2.acquireShared(0);
863 +        sync.acquire();
864 +        assertHasWaitersLocked(sync, c, t1, t2);
865 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
866 +        assertEquals(2, sync.getWaitQueueLength(c));
867 +        c.signalAll();
868 +        assertHasWaitersLocked(sync, c, NO_THREADS);
869 +        assertHasExclusiveQueuedThreads(sync, t1, t2);
870 +        assertEquals(0, sync.getWaitQueueLength(c));
871 +        sync.release();
872 +
873 +        awaitTermination(t1);
874 +        awaitTermination(t2);
875 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
876 +    }
877 +
878 +    /**
879 +     * getWaitingThreads returns only and all waiting threads
880 +     */
881 +    public void testGetWaitingThreads() {
882 +        final Mutex sync = new Mutex();
883 +        final ConditionObject c = sync.newCondition();
884 +        final BooleanLatch acquired1 = new BooleanLatch();
885 +        final BooleanLatch acquired2 = new BooleanLatch();
886 +        final Thread t1 = new Thread(new CheckedRunnable() {
887 +            public void realRun() throws InterruptedException {
888 +                sync.acquire();
889 +                assertHasWaitersLocked(sync, c, NO_THREADS);
890 +                assertTrue(sync.getWaitingThreads(c).isEmpty());
891 +                assertTrue(acquired1.releaseShared(0));
892 +                c.await();
893 +                sync.release();
894 +            }});
895 +
896 +        final Thread t2 = new Thread(new CheckedRunnable() {
897 +            public void realRun() throws InterruptedException {
898 +                sync.acquire();
899 +                assertHasWaitersLocked(sync, c, t1);
900 +                assertTrue(sync.getWaitingThreads(c).contains(t1));
901 +                assertFalse(sync.getWaitingThreads(c).isEmpty());
902 +                assertEquals(1, sync.getWaitingThreads(c).size());
903 +                assertTrue(acquired2.releaseShared(0));
904 +                c.await();
905 +                sync.release();
906 +            }});
907 +
908 +        sync.acquire();
909 +        assertHasWaitersLocked(sync, c, NO_THREADS);
910 +        assertFalse(sync.getWaitingThreads(c).contains(t1));
911 +        assertFalse(sync.getWaitingThreads(c).contains(t2));
912 +        assertTrue(sync.getWaitingThreads(c).isEmpty());
913 +        assertEquals(0, sync.getWaitingThreads(c).size());
914 +        sync.release();
915 +
916 +        t1.start();
917 +        acquired1.acquireShared(0);
918 +        sync.acquire();
919 +        assertHasWaitersLocked(sync, c, t1);
920 +        assertTrue(sync.getWaitingThreads(c).contains(t1));
921 +        assertFalse(sync.getWaitingThreads(c).contains(t2));
922 +        assertFalse(sync.getWaitingThreads(c).isEmpty());
923 +        assertEquals(1, sync.getWaitingThreads(c).size());
924 +        sync.release();
925 +
926 +        t2.start();
927 +        acquired2.acquireShared(0);
928 +        sync.acquire();
929 +        assertHasWaitersLocked(sync, c, t1, t2);
930 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
931 +        assertTrue(sync.getWaitingThreads(c).contains(t1));
932 +        assertTrue(sync.getWaitingThreads(c).contains(t2));
933 +        assertFalse(sync.getWaitingThreads(c).isEmpty());
934 +        assertEquals(2, sync.getWaitingThreads(c).size());
935 +        c.signalAll();
936 +        assertHasWaitersLocked(sync, c, NO_THREADS);
937 +        assertHasExclusiveQueuedThreads(sync, t1, t2);
938 +        assertFalse(sync.getWaitingThreads(c).contains(t1));
939 +        assertFalse(sync.getWaitingThreads(c).contains(t2));
940 +        assertTrue(sync.getWaitingThreads(c).isEmpty());
941 +        assertEquals(0, sync.getWaitingThreads(c).size());
942 +        sync.release();
943 +
944 +        awaitTermination(t1);
945 +        awaitTermination(t2);
946 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
947 +    }
948 +
949 +    /**
950 +     * awaitUninterruptibly doesn't abort on interrupt
951 +     */
952 +    public void testAwaitUninterruptibly() {
953 +        final Mutex sync = new Mutex();
954 +        final ConditionObject c = sync.newCondition();
955 +        final BooleanLatch acquired = new BooleanLatch();
956 +        Thread t = newStartedThread(new CheckedRunnable() {
957 +            public void realRun() {
958 +                sync.acquire();
959 +                assertTrue(acquired.releaseShared(0));
960 +                c.awaitUninterruptibly();
961 +                assertTrue(Thread.interrupted());
962 +                assertHasWaitersLocked(sync, c, NO_THREADS);
963 +                sync.release();
964 +            }});
965 +
966 +        acquired.acquireShared(0);
967 +        sync.acquire();
968 +        assertHasWaitersLocked(sync, c, t);
969 +        sync.release();
970 +        t.interrupt();
971 +        assertHasWaitersUnlocked(sync, c, t);
972 +        assertThreadStaysAlive(t);
973 +        sync.acquire();
974 +        assertHasWaitersLocked(sync, c, t);
975 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
976 +        c.signal();
977 +        assertHasWaitersLocked(sync, c, NO_THREADS);
978 +        assertHasExclusiveQueuedThreads(sync, t);
979 +        sync.release();
980 +        awaitTermination(t);
981 +    }
982 +
983 +    /**
984 +     * await/awaitNanos/awaitUntil is interruptible
985 +     */
986 +    public void testInterruptible_await()      { testInterruptible(AwaitMethod.await); }
987 +    public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
988 +    public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
989 +    public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
990 +    public void testInterruptible(final AwaitMethod awaitMethod) {
991 +        final Mutex sync = new Mutex();
992 +        final ConditionObject c = sync.newCondition();
993 +        final BooleanLatch acquired = new BooleanLatch();
994 +        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
995 +            public void realRun() throws InterruptedException {
996 +                sync.acquire();
997 +                assertTrue(acquired.releaseShared(0));
998 +                await(c, awaitMethod);
999 +            }});
1000 +
1001 +        acquired.acquireShared(0);
1002 +        t.interrupt();
1003 +        awaitTermination(t);
1004 +    }
1005 +
1006 +    /**
1007 +     * signalAll wakes up all threads
1008 +     */
1009 +    public void testSignalAll_await()      { testSignalAll(AwaitMethod.await); }
1010 +    public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
1011 +    public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
1012 +    public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
1013 +    public void testSignalAll(final AwaitMethod awaitMethod) {
1014 +        final Mutex sync = new Mutex();
1015 +        final ConditionObject c = sync.newCondition();
1016 +        final BooleanLatch acquired1 = new BooleanLatch();
1017 +        final BooleanLatch acquired2 = new BooleanLatch();
1018 +        Thread t1 = newStartedThread(new CheckedRunnable() {
1019 +            public void realRun() throws InterruptedException {
1020 +                sync.acquire();
1021 +                acquired1.releaseShared(0);
1022 +                await(c, awaitMethod);
1023 +                sync.release();
1024 +            }});
1025 +
1026 +        Thread t2 = newStartedThread(new CheckedRunnable() {
1027 +            public void realRun() throws InterruptedException {
1028 +                sync.acquire();
1029 +                acquired2.releaseShared(0);
1030 +                await(c, awaitMethod);
1031 +                sync.release();
1032 +            }});
1033 +
1034 +        acquired1.acquireShared(0);
1035 +        acquired2.acquireShared(0);
1036 +        sync.acquire();
1037 +        assertHasWaitersLocked(sync, c, t1, t2);
1038 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1039 +        c.signalAll();
1040 +        assertHasWaitersLocked(sync, c, NO_THREADS);
1041 +        assertHasExclusiveQueuedThreads(sync, t1, t2);
1042 +        sync.release();
1043 +        awaitTermination(t1);
1044 +        awaitTermination(t2);
1045 +    }
1046 +
1047 +    /**
1048 +     * toString indicates current state
1049 +     */
1050 +    public void testToString() {
1051 +        Mutex sync = new Mutex();
1052 +        assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
1053 +        sync.acquire();
1054 +        assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
1055 +    }
1056 +
1057 +    /**
1058 +     * A serialized AQS deserializes with current state, but no queued threads
1059 +     */
1060 +    public void testSerialization() {
1061 +        Mutex sync = new Mutex();
1062 +        assertFalse(serialClone(sync).isHeldExclusively());
1063 +        sync.acquire();
1064 +        Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
1065 +        waitForQueuedThread(sync, t);
1066 +        assertTrue(sync.isHeldExclusively());
1067 +
1068 +        Mutex clone = serialClone(sync);
1069 +        assertTrue(clone.isHeldExclusively());
1070 +        assertHasExclusiveQueuedThreads(sync, t);
1071 +        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
1072 +        t.interrupt();
1073 +        awaitTermination(t);
1074 +        sync.release();
1075 +        assertFalse(sync.isHeldExclusively());
1076 +        assertTrue(clone.isHeldExclusively());
1077 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1078 +        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
1079 +    }
1080  
1081      /**
1082 <     * Latch isSignalled initially returns false, then true after release
1082 >     * tryReleaseShared setting state changes getState
1083       */
1084 <    public void testLatchIsSignalled() {
1085 <        final BooleanLatch l = new BooleanLatch();
1086 <        assertFalse(l.isSignalled());
1087 <        l.releaseShared(0);
1088 <        assertTrue(l.isSignalled());
1084 >    public void testGetStateWithReleaseShared() {
1085 >        final BooleanLatch l = new BooleanLatch();
1086 >        assertFalse(l.isSignalled());
1087 >        assertTrue(l.releaseShared(0));
1088 >        assertTrue(l.isSignalled());
1089      }
1090  
1091      /**
1092 <     * release and has no effect when already signalled
1092 >     * releaseShared has no effect when already signalled
1093       */
1094      public void testReleaseShared() {
1095 <        final BooleanLatch l = new BooleanLatch();
1096 <        assertFalse(l.isSignalled());
1097 <        l.releaseShared(0);
1098 <        assertTrue(l.isSignalled());
1099 <        l.releaseShared(0);
1100 <        assertTrue(l.isSignalled());
1095 >        final BooleanLatch l = new BooleanLatch();
1096 >        assertFalse(l.isSignalled());
1097 >        assertTrue(l.releaseShared(0));
1098 >        assertTrue(l.isSignalled());
1099 >        assertTrue(l.releaseShared(0));
1100 >        assertTrue(l.isSignalled());
1101      }
1102  
1103      /**
1104       * acquireSharedInterruptibly returns after release, but not before
1105       */
1106      public void testAcquireSharedInterruptibly() {
1107 <        final BooleanLatch l = new BooleanLatch();
1107 >        final BooleanLatch l = new BooleanLatch();
1108  
1109 <        Thread t = new Thread(new Runnable() {
1110 <                public void run() {
1111 <                    try {
1112 <                        threadAssertFalse(l.isSignalled());
1113 <                        l.acquireSharedInterruptibly(0);
1114 <                        threadAssertTrue(l.isSignalled());
1115 <                    } catch(InterruptedException e){
1116 <                        threadUnexpectedException();
1117 <                    }
1118 <                }
1119 <            });
1120 <        try {
1121 <            t.start();
1122 <            assertFalse(l.isSignalled());
1123 <            Thread.sleep(SHORT_DELAY_MS);
1124 <            l.releaseShared(0);
568 <            assertTrue(l.isSignalled());
569 <            t.join();
570 <        } catch (InterruptedException e){
571 <            unexpectedException();
572 <        }
573 <    }
574 <    
575 <
576 <    /**
577 <     * acquireSharedTimed returns after release
578 <     */
579 <    public void testAsquireSharedTimed() {
580 <        final BooleanLatch l = new BooleanLatch();
581 <
582 <        Thread t = new Thread(new Runnable() {
583 <                public void run() {
584 <                    try {
585 <                        threadAssertFalse(l.isSignalled());
586 <                        threadAssertTrue(l.acquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
587 <                        threadAssertTrue(l.isSignalled());
588 <
589 <                    } catch(InterruptedException e){
590 <                        threadUnexpectedException();
591 <                    }
592 <                }
593 <            });
594 <        try {
595 <            t.start();
596 <            assertFalse(l.isSignalled());
597 <            Thread.sleep(SHORT_DELAY_MS);
598 <            l.releaseShared(0);
599 <            assertTrue(l.isSignalled());
600 <            t.join();
601 <        } catch (InterruptedException e){
602 <            unexpectedException();
603 <        }
1109 >        Thread t = newStartedThread(new CheckedRunnable() {
1110 >            public void realRun() throws InterruptedException {
1111 >                assertFalse(l.isSignalled());
1112 >                l.acquireSharedInterruptibly(0);
1113 >                assertTrue(l.isSignalled());
1114 >                l.acquireSharedInterruptibly(0);
1115 >                assertTrue(l.isSignalled());
1116 >            }});
1117 >
1118 >        waitForQueuedThread(l, t);
1119 >        assertFalse(l.isSignalled());
1120 >        assertThreadStaysAlive(t);
1121 >        assertHasSharedQueuedThreads(l, t);
1122 >        assertTrue(l.releaseShared(0));
1123 >        assertTrue(l.isSignalled());
1124 >        awaitTermination(t);
1125      }
1126 <    
1126 >
1127      /**
1128 <     * acquireSharedInterruptibly throws IE if interrupted before released
1128 >     * tryAcquireSharedNanos returns after release, but not before
1129       */
1130 <    public void testAcquireSharedInterruptibly_InterruptedException() {
1130 >    public void testTryAcquireSharedNanos() {
1131          final BooleanLatch l = new BooleanLatch();
1132 <        Thread t = new Thread(new Runnable() {
1133 <                public void run() {
1134 <                    try {
1135 <                        threadAssertFalse(l.isSignalled());
1136 <                        l.acquireSharedInterruptibly(0);
1137 <                        threadShouldThrow();
1138 <                    } catch(InterruptedException success){}
1139 <                }
1140 <            });
1141 <        t.start();
1142 <        try {
1143 <            assertFalse(l.isSignalled());
1144 <            t.interrupt();
1145 <            t.join();
1146 <        } catch (InterruptedException e){
1147 <            unexpectedException();
1148 <        }
1132 >
1133 >        Thread t = newStartedThread(new CheckedRunnable() {
1134 >            public void realRun() throws InterruptedException {
1135 >                assertFalse(l.isSignalled());
1136 >                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1137 >                assertTrue(l.tryAcquireSharedNanos(0, nanos));
1138 >                assertTrue(l.isSignalled());
1139 >                assertTrue(l.tryAcquireSharedNanos(0, nanos));
1140 >                assertTrue(l.isSignalled());
1141 >            }});
1142 >
1143 >        waitForQueuedThread(l, t);
1144 >        assertFalse(l.isSignalled());
1145 >        assertThreadStaysAlive(t);
1146 >        assertTrue(l.releaseShared(0));
1147 >        assertTrue(l.isSignalled());
1148 >        awaitTermination(t);
1149      }
1150  
1151      /**
1152 <     * acquireSharedTimed throws IE if interrupted before released
1152 >     * acquireSharedInterruptibly is interruptible
1153       */
1154 <    public void testAcquireSharedNanos_InterruptedException() {
1154 >    public void testAcquireSharedInterruptibly_Interruptible() {
1155          final BooleanLatch l = new BooleanLatch();
1156 <        Thread t = new Thread(new Runnable() {
1157 <                public void run() {
1158 <                    try {
1159 <                        threadAssertFalse(l.isSignalled());
1160 <                        l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
1161 <                        threadShouldThrow();                        
1162 <                    } catch(InterruptedException success){}
1163 <                }
1164 <            });
1165 <        t.start();
1166 <        try {
646 <            Thread.sleep(SHORT_DELAY_MS);
647 <            assertFalse(l.isSignalled());
648 <            t.interrupt();
649 <            t.join();
650 <        } catch (InterruptedException e){
651 <            unexpectedException();
652 <        }
1156 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1157 >            public void realRun() throws InterruptedException {
1158 >                assertFalse(l.isSignalled());
1159 >                l.acquireSharedInterruptibly(0);
1160 >            }});
1161 >
1162 >        waitForQueuedThread(l, t);
1163 >        assertFalse(l.isSignalled());
1164 >        t.interrupt();
1165 >        awaitTermination(t);
1166 >        assertFalse(l.isSignalled());
1167      }
1168  
1169      /**
1170 <     * acquireSharedTimed times out if not released before timeout
1170 >     * tryAcquireSharedNanos is interruptible
1171       */
1172 <    public void testAcquireSharedNanos_Timeout() {
1172 >    public void testTryAcquireSharedNanos_Interruptible() {
1173          final BooleanLatch l = new BooleanLatch();
1174 <        Thread t = new Thread(new Runnable() {
1175 <                public void run() {
1176 <                    try {
1177 <                        threadAssertFalse(l.isSignalled());
1178 <                        threadAssertFalse(l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
1179 <                    } catch(InterruptedException ie){
1180 <                        threadUnexpectedException();
1181 <                    }
1182 <                }
1183 <            });
1184 <        t.start();
1185 <        try {
1186 <            Thread.sleep(SHORT_DELAY_MS);
1187 <            assertFalse(l.isSignalled());
1188 <            t.join();
1189 <        } catch (InterruptedException e){
1190 <            unexpectedException();
1191 <        }
1174 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1175 >            public void realRun() throws InterruptedException {
1176 >                assertFalse(l.isSignalled());
1177 >                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1178 >                l.tryAcquireSharedNanos(0, nanos);
1179 >            }});
1180 >
1181 >        waitForQueuedThread(l, t);
1182 >        assertFalse(l.isSignalled());
1183 >        t.interrupt();
1184 >        awaitTermination(t);
1185 >        assertFalse(l.isSignalled());
1186 >    }
1187 >
1188 >    /**
1189 >     * tryAcquireSharedNanos times out if not released before timeout
1190 >     */
1191 >    public void testTryAcquireSharedNanos_Timeout() {
1192 >        final BooleanLatch l = new BooleanLatch();
1193 >        Thread t = newStartedThread(new CheckedRunnable() {
1194 >            public void realRun() throws InterruptedException {
1195 >                assertFalse(l.isSignalled());
1196 >                long startTime = System.nanoTime();
1197 >                long nanos = MILLISECONDS.toNanos(timeoutMillis());
1198 >                assertFalse(l.tryAcquireSharedNanos(0, nanos));
1199 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
1200 >                assertFalse(l.isSignalled());
1201 >            }});
1202 >
1203 >        waitForQueuedThread(l, t);
1204 >        assertFalse(l.isSignalled());
1205 >        awaitTermination(t);
1206 >        assertFalse(l.isSignalled());
1207      }
1208 <    
1208 >
1209   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines