private void dispatchWhenReady(final Collection<RowProcessingPublisher> rowProcessingPublishers, final TaskListener rowProcessorPublishersDoneCompletionListener) { final LinkedList<RowProcessingPublisher> remainingPublishers = new LinkedList<>(rowProcessingPublishers); while (!remainingPublishers.isEmpty()) { boolean progressThisIteration = false; for (final Iterator<RowProcessingPublisher> it = remainingPublishers.iterator(); it.hasNext(); ) { final RowProcessingPublisher rowProcessingPublisher = it.next(); final boolean started = rowProcessingPublisher .runRowProcessing(_resultQueue, rowProcessorPublishersDoneCompletionListener); if (started) { logger.debug("Scheduled row processing publisher: {}", rowProcessingPublisher); it.remove(); progressThisIteration = true; } } if (!progressThisIteration) { try { // Give way for the data processing to happen in other // threads. Better to sleep() than to yield(). Thread.sleep(100); } catch (final InterruptedException e) { // do nothing } } } }