public void execute(final PrioritizableRunnable runnable) {
    _queue.add(runnable);
    // Guarantees that execution loop is scheduled only once to the underlying executor.
    // Also makes sure that all memory effects of last Runnable are visible to the next Runnable
    // in case value returned by decrementAndGet == 0.
    if (_pendingCount.getAndIncrement() == 0) {
      tryExecuteLoop();
    }
  }
@Test(dataProvider = "draining")
  public void testRejectOnFirstExecute(boolean draining) throws InterruptedException {
    // First fill up the underlying executor service so that a subsequent
    // submission of an execution loop by the serial executor will fail.
    _executorService.execute(new NeverEndingRunnable());
    assertFalse(_rejectionHandler.wasExecuted());
    _executorService.execute(new NeverEndingRunnable());
    assertFalse(_rejectionHandler.wasExecuted());

    // Now submit our task to serial executor. The underlying executor should
    // throw RejectedExecutionException and the rejectionRunnable should run.
    _serialExecutor.execute(new NeverEndingRunnable());
    assertTrue(_rejectionHandler.await(5, TimeUnit.SECONDS));
    assertTrue(
        "Expected " + _rejectionHandler.getLastError() + " to be instance of "
            + RejectedExecutionException.class.getName(),
        _rejectionHandler.getLastError() instanceof RejectedExecutionException);
  }