code: private void performReads(ReadResult readResult) throws InterruptedException {
      long start = System.currentTimeMillis();
      for (int i = 0; i < streams.length; ) {
        boolean acquired = slots.tryAcquire(1, 10, TimeUnit.SECONDS);
        reporter.progress();
        if (acquired) {
          readPool.execute(new ReadOperation(readResult, i));
          i++;
        }
      }
      // All read operations have been submitted to the readPool.
      // Now wait for the operations to finish and release the semaphore.
      while (true) {
        boolean acquired =
          slots.tryAcquire(numThreads, 10, TimeUnit.SECONDS);
        reporter.progress();
        if (acquired) {
          slots.release(numThreads);
          break;
        }
      }
  
      readTime += (System.currentTimeMillis() - start);
    }
docs: Performs a batch of reads from the given streams and waits
  for the reads to finish.