Java:并行调用API 200次,但预期不会返回

时间:2018-11-30 10:01:27

标签: java parallel-processing executorservice

我想调用REST API 200次,但不确定执行正确的方法:

ExecutorService es = Executors.newFixedThreadPool(200);

for (i = 0 ; i<200 ; i++) {
    if (check == true) {
        es.submit() -> callTrueAPI();
    } else {
        es.submit() ->callFalseAPI();
    }

    es.shutdown;

这是正确的方法吗?

3 个答案:

答案 0 :(得分:1)

您的语法不正确。应该是:

ExecutorService es = Executors.newFixedThreadPool(200);

for (int i = 0; i < 200; i++) {
    if (check) {
        es.submit(() -> callTrueAPI());
    } else {
        es.submit(() -> callFalseAPI());
    }
}

es.shutdown();

shutdown之后,线程池将继续直到所有任务完成。如果您要等到任务完成,请在awaitTermination调用后调用shutdown


此方法存在问题。您实际上是在创建一个具有200个线程的池,然后销毁线程(然后该池将关闭)。这在CPU和内存上都很昂贵。如果您想更有效地执行此操作(就客户端资源而言):

  1. 使用较小的线程池(!)
  2. 回收池...尽管这将涉及使用其他方法来等待任务完成。

假设REST调用将去往另一个服务/进程,则您可能启动的线程数可能超过内核数,并让它们并行进行。但是,远程服务可能会限制同时执行的请求数量,因此200个请求可能会在服务器的输入队列中“备份”,这可能导致请求超时,5xx错误等。因此,一次触发200个请求对整体吞吐量不太可能。

如果您将此作为压力测试,则有更现实的方法来进行;参见@Karol的答案。

答案 1 :(得分:0)

除非您拥有200个CPU内核,否则您将无法在同一时间发送200个请求。至少Java线程将无法同时执行。如果您有一个具有4个核心的常规CPU,则最可能通过拥有4个工作线程(每个线程将请求发送50次)来获得更好的结果,这将减少上下文切换的时间。

使用Apache JMeterGatling来创建适当的测试计划可能会更容易,该计划具有上升和下降时间来模拟所需的流量。这些工具是为您所描述的确切目的而构建的,并且提供了许多出色的示例。

答案 2 :(得分:0)

这是Java版本> = 8的紧凑版本:

    ExecutorService es = Executors.newFixedThreadPool(200);

    IntStream.range(0, 200).forEach((i) -> es.submit(() -> check ? callTrueAPI() : callFalseAPI()));

    es.shutdown();