code: public void run(Collection<Runnable> tasks) {
          // Create a semphore that the wrapped runnables will execute
          int numTasks = tasks.size();
          CountDownLatch latch = new CountDownLatch(numTasks);
          for (Runnable r : tasks) {
              if (r == null)
                  throw new NullPointerException("Cannot run null tasks");
              workQueue.offer(new CountingRunnable(r, latch));
          }
          try {
              // Wait until all the tasks have finished
              latch.await();
          }
          catch (InterruptedException ie) {
              throw new IllegalStateException("Not all tasks finished", ie);
          }
      }
docs: Executes the tasks using a thread pool and returns once all tasks have
  finished.
  
  @throws IllegalStateException if interrupted while waiting for the tasks
  to finish