/** getWaitQueueLength returns number of waiting threads */
  public void testGetWaitQueueLength() {
    final Mutex sync = new Mutex();
    final ConditionObject c = sync.newCondition();
    final BooleanLatch acquired1 = new BooleanLatch();
    final BooleanLatch acquired2 = new BooleanLatch();
    final Thread t1 =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                assertHasWaitersLocked(sync, c, NO_THREADS);
                assertEquals(0, sync.getWaitQueueLength(c));
                assertTrue(acquired1.releaseShared(0));
                c.await();
                sync.release();
              }
            });
    acquired1.acquireShared(0);
    sync.acquire();
    assertHasWaitersLocked(sync, c, t1);
    assertEquals(1, sync.getWaitQueueLength(c));
    sync.release();

    final Thread t2 =
        newStartedThread(
            new CheckedRunnable() {
              public void realRun() throws InterruptedException {
                sync.acquire();
                assertHasWaitersLocked(sync, c, t1);
                assertEquals(1, sync.getWaitQueueLength(c));
                assertTrue(acquired2.releaseShared(0));
                c.await();
                sync.release();
              }
            });
    acquired2.acquireShared(0);
    sync.acquire();
    assertHasWaitersLocked(sync, c, t1, t2);
    assertHasExclusiveQueuedThreads(sync, NO_THREADS);
    assertEquals(2, sync.getWaitQueueLength(c));
    c.signalAll();
    assertHasWaitersLocked(sync, c, NO_THREADS);
    assertHasExclusiveQueuedThreads(sync, t1, t2);
    assertEquals(0, sync.getWaitQueueLength(c));
    sync.release();

    awaitTermination(t1);
    awaitTermination(t2);
    assertHasWaitersUnlocked(sync, c, NO_THREADS);
  }
 /** getWaitQueueLength(null) throws NullPointerException */
 public void testGetWaitQueueLengthNPE() {
   final Mutex sync = new Mutex();
   try {
     sync.getWaitQueueLength(null);
     shouldThrow();
   } catch (NullPointerException success) {
   }
 }
 /** Checks that condition c has exactly the given waiter threads. */
 void assertHasWaitersLocked(Mutex sync, ConditionObject c, Thread... threads) {
   assertEquals(threads.length > 0, sync.hasWaiters(c));
   assertEquals(threads.length, sync.getWaitQueueLength(c));
   assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
   assertEquals(threads.length, sync.getWaitingThreads(c).size());
   assertEquals(
       new HashSet<Thread>(sync.getWaitingThreads(c)),
       new HashSet<Thread>(Arrays.asList(threads)));
 }
 /** getWaitQueueLength throws IllegalMonitorStateException if not synced */
 public void testGetWaitQueueLengthIMSE() {
   final Mutex sync = new Mutex();
   final ConditionObject c = sync.newCondition();
   try {
     sync.getWaitQueueLength(c);
     shouldThrow();
   } catch (IllegalMonitorStateException success) {
   }
   assertHasWaitersUnlocked(sync, c, NO_THREADS);
 }