private void doMultipleClients(final Class<? extends Test> cmd) throws IOException {
    final List<Thread> threads = new ArrayList<>(this.N);
    final long[] timings = new long[this.N];
    final int perClientRows = R / N;
    final TableName tableName = this.tableName;
    final DataBlockEncoding encoding = this.blockEncoding;
    final boolean flushCommits = this.flushCommits;
    final Compression.Algorithm compression = this.compression;
    final boolean writeToWal = this.writeToWAL;
    final int preSplitRegions = this.presplitRegions;
    final boolean useTags = this.useTags;
    final int numTags = this.noOfTags;
    final Connection connection = ConnectionFactory.createConnection(getConf());
    for (int i = 0; i < this.N; i++) {
      final int index = i;
      Thread t = new Thread("TestClient-" + i) {
        @Override
        public void run() {
          super.run();
          PerformanceEvaluation pe = new PerformanceEvaluation(getConf());
          pe.tableName = tableName;
          pe.blockEncoding = encoding;
          pe.flushCommits = flushCommits;
          pe.compression = compression;
          pe.writeToWAL = writeToWal;
          pe.presplitRegions = preSplitRegions;
          pe.N = N;
          pe.connection = connection;
          pe.useTags = useTags;
          pe.noOfTags = numTags;
          try {
            long elapsedTime = pe.runOneClient(cmd, index * perClientRows, perClientRows, R,
              flushCommits, writeToWAL, useTags, noOfTags, connection,
              msg -> LOG.info("client-" + getName() + " " + msg));
            timings[index] = elapsedTime;
            LOG.info("Finished " + getName() + " in " + elapsedTime + "ms writing " + perClientRows
              + " rows");
          } catch (IOException e) {
            throw new RuntimeException(e);
          }
        }
      };
      threads.add(t);
    }
    for (Thread t : threads) {
      t.start();
    }
    for (Thread t : threads) {
      while (t.isAlive()) {
        try {
          t.join();
        } catch (InterruptedException e) {
          LOG.debug("Interrupted, continuing" + e.toString());
        }
      }
    }
    final String test = cmd.getSimpleName();
    LOG.info("[" + test + "] Summary of timings (ms): " + Arrays.toString(timings));
    Arrays.sort(timings);
    long total = 0;
    for (int i = 0; i < this.N; i++) {
      total += timings[i];
    }
    LOG.info("[" + test + "]" + "\tMin: " + timings[0] + "ms" + "\tMax: " + timings[this.N - 1]
      + "ms" + "\tAvg: " + (total / this.N) + "ms");
  }
Run all clients in this vm each to its own thread.
@param cmd Command to run
@throws IOException if creating a connection fails
hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/PerformanceEvaluation.java