-2

I have a method which makes lets say 100k http calls to an API, for that reason I am making the http calls concurrently to avoid http bottleneck. But I would also like to time the whole method without blocking any threads.

        ExecutorService service = Executors.newFixedThreadPool(500);
        for (int i = 0; i < 100_000; i++) {
            int finalI = i;
            Runnable runnable = () -> {
                // My http call goes here....
            };
            service.submit(runnable);
        }
SomeOnionGamer
  • 203
  • 1
  • 4
  • 8
  • 3
    Making HTTP calls concurrently to the same server won't save you much. There is only one network, and it isn't concurrent. And the only 'calculation' required is end time minus start time. This is really measurement, not calculation. – user207421 Jul 02 '22 at 10:57
  • Relevant question and answers: https://stackoverflow.com/questions/37172989/measuring-execution-time-for-multithreaded-java-application – JustAnotherDeveloper Jul 02 '22 at 11:01

1 Answers1

1

If you wish to get a rough idea of the time the whole set of operations takes then use shutdown then awaitTermination to wait for the executor service to finish all of the submitted tasks. Here is a simple example:

long start= System.nanoTime();
ExecutorService exec = Executors.newFixedThreadPool(100);
try {
    for (int i = 0; i < 100_000; i++) {
        final int x = i;
        Runnable runnable = () -> System.out.println(x);
        exec.submit(runnable);
    }
} finally {
    exec.shutdown();
    exec.awaitTermination(365, TimeUnit.DAYS);
}
long elapsed = System.nanoTime() - start;
System.out.println("Elapsed millisec "+TimeUnit.NANOSECONDS.toMillis(elapsed));

It's not a good idea to put System.out.println or other logging inside the tasks as then you are only timing your console I/O, and not getting an estimate of how quick your processing is.

As in the comments, using multi-thread access to same set of servers / resource / disk can make overall elapsed time get longer or cause issues elsewhere.

From JDK19 the ExecutorService is AutoCloseable so you can simplify the try block and remove the finally:

try (ExecutorService exec = Executors.newFixedThreadPool(100)) {
     ...
}
DuncG
  • 12,137
  • 2
  • 21
  • 33