import java.net.URI; import java.net.http.*; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; /** Fires TOTAL requests with THREADS threads and reports how long each batch of BATCH took. */ public class Warmup { public static void main(String[] a) throws Exception { int port = Integer.parseInt(a[0]); int total = 20_000, batch = 2_000, threads = 4; HttpClient c = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build(); HttpRequest rq = HttpRequest.newBuilder(URI.create("http://localhost:" + port + "/hello")).build(); AtomicInteger done = new AtomicInteger(); long[] batchEnd = new long[total / batch]; long t0 = System.nanoTime(); ExecutorService ex = Executors.newFixedThreadPool(threads); List> fs = new ArrayList<>(); for (int t = 0; t < threads; t++) fs.add(ex.submit(() -> { try { while (true) { int n = done.incrementAndGet(); if (n > total) return null; c.send(rq, HttpResponse.BodyHandlers.discarding()); if (n % batch == 0) batchEnd[n / batch - 1] = System.nanoTime(); } } catch (Exception e) { throw new RuntimeException(e); } })); for (Future f : fs) f.get(); ex.shutdown(); StringBuilder sb = new StringBuilder("batch ms:"); long prev = t0; for (long e : batchEnd) { sb.append(' ').append((e - prev) / 1_000_000); prev = e; } System.out.println(sb); System.out.println("total ms: " + (prev - t0) / 1_000_000); } }