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

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines