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