WorkQueue { public WorkQueue( final int maxQueueSize) { this.exceptions = Collections.synchronizedList(new ArrayList<>()); this.feederThread = Thread.currentThread().getId(); this.maxQueueSize = maxQueueSize; this.executor = createNewExecutor(); } WorkQueue(
            final int maxQueueSize); void scheduleShutdown(); @SuppressWarnings("CallToNotifyInsteadOfNotifyAll") void startOrWait(@Nonnull final Runnable workLoad, final long timeout); void startOrWait(@Nonnull final Runnable workLoad); boolean waitUntilFinished(final long timeout); boolean waitUntilFinished(); boolean isEmptyAndFinished(); void addException(@Nonnull final Exception exception); @Nonnull List<Exception> getExceptions();  }
@Test public void testWorkQueue() throws InterruptedException { LOG.info("testWorkQueue"); total.set(0); final int maxQueueSize = 10000; final WorkQueue queue = new WorkQueue(maxQueueSize); final int totalTasks = maxQueueSize * 10; for (int i = 0; i < totalTasks; ++i) { queue.startOrWait(() -> { total.incrementAndGet(); for (int x = 0; x < 1000; ++x) { assert Math.sqrt((double) x) >= 0; } }); if ((i % 100) == 0) { LOG.debug("testWorkQueue: i={}", i); } } Assert.assertTrue(queue.waitUntilFinished()); Assert.assertEquals(totalTasks, total.get()); queue.scheduleShutdown(); }