code: private void runWorkLoop() throws InterruptedException, ExecutionException {
          // Get next work unit from queue
          for (;;) {
              // Check for interruption
              interruptionChecker.check();
  
              // Get next work unit
              final WorkUnitWrapper<T> workUnitWrapper = workUnits.take();
  
              if (workUnitWrapper.workUnit == null) {
                  // Received poison pill
                  break;
              }
  
              // Process the work unit
              try {
                  // Process the work unit (may throw InterruptedException) 
                  workUnitProcessor.processWorkUnit(workUnitWrapper.workUnit, this, log);
  
              } catch (InterruptedException | OutOfMemoryError e) {
                  // On InterruptedException or OutOfMemoryError, drain work queue, send poison pills, and re-throw
                  workUnits.clear();
                  sendPoisonPills();
                  throw e;
  
              } catch (final RuntimeException e) {
                  // On unchecked exception, drain work queue, send poison pills, and throw ExecutionException
                  workUnits.clear();
                  sendPoisonPills();
                  throw new ExecutionException("Worker thread threw unchecked exception", e);
  
              } finally {
                  if (numIncompleteWorkUnits.decrementAndGet() == 0) {
                      // No more work units -- send poison pills
                      sendPoisonPills();
                  }
              }
          }
      }
docs: Start a worker. Called by startWorkers(), but should also be called by the main thread to do some of the work
  on that thread, to prevent deadlock in the case that the ExecutorService doesn't have as many threads
  available as numParallelTasks. When this method returns, either all the work has been completed, or this or
  some other thread was interrupted. If InterruptedException is thrown, this thread or another was interrupted.
  
  @throws InterruptedException
  if a worker thread was interrupted
  @throws ExecutionException
  if a worker thread throws an uncaught exception