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