gpt4 book ai didi

Java - 异步 - 线程池

转载 作者:太空宇宙 更新时间:2023-11-04 11:40:01 25 4
gpt4 key购买 nike

我正在尝试了解 java 中异步的好处。

场景 1:我有一个 Spring Boot Web 应用程序部署到 tomcat,tomcat 最小和最大线程都设置为 200。

@Service
public class MyService{

public String execute(){
try {
//simulate blocking
Thread.sleep(3000);
} catch (InterruptedException e) {}
return "OK";
}
}

@RestController
public class MyController {

@Autowired
private MyService service;

@RequestMapping("/test")
public String test(){
return service.execute();
}
}

场景 2:我有一个 Spring Boot Web 应用程序部署到 tomcat,tomcat 最小和最大线程均设置为 100

@Service
public class MyService{

public String execute(){
try {
//simulate blocking
Thread.sleep(3000);
} catch (InterruptedException e) {}
return "OK";
}
}

@RestController
public class MyController {

@Autowired
private MyService service;

private ExecutorService executorService = Executors.newFixedThreadPool(100);

@RequestMapping("/test")
public DeferredResult<String> test(){
DeferredResult<String> deferredResult = new DeferredResult<>();
CompletableFuture.supplyAsync(service::execute, executorService).
whenCompleteAsync((result, throwable) -> deferredResult.setResult(result));
return deferredResult;
}
}

在每个场景中,线程总数均为 200。

但我不认为场景 2 会表现得更好:

在场景 1 中,如果同时传入 400 个请求,则前 200 个请求将由 200 个 http 线程提供服务,接下来的 200 个请求将必须等待 3 秒(加上一点),直到其中一个线程再次可用。

因此吞吐量为每 6 秒 400 个请求 = 每秒 66.6 个请求。

平均响应时间为 (200 * 3 + 200 * 6)/(400) = 4.5 秒

在场景 2 中,如果同时有 400 个请求进来。前 100 个请求将立即由 100 个 http 线程提供服务,每个线程将调用服务,不等待结果,然后立即恢复,并可用于服务接下来的 100 个请求。但现在对于第二个 100 个请求,当每个 http 线程调用该服务时,该服务当前正在等待 3 秒(减去一点)来完成处理前 100 个线程。所以接下来的 100 个会排队(在 executorservice 的线程池中)。因此,我们几乎很快就处理了所有 400 个请求,但是100 个正在服务中处理(等待 3 秒),而 300 个在执行程序服务线程池中排队。 3 秒后,前 100 个处理完成,接下来的 100 个出列并处理,依此类推。

因此吞吐量为 12 秒内 400 个请求 = 每秒 33.3 个请求

平均响应时间为(100 * 3 + 100 * 6 + 100 * 9 + 100 * 12)/(400) = 7.5 秒

现在,有人可能会说,“我可以通过增加执行程序服务线程池中的线程数来改进场景 2”,对此我可以回答,“好吧,那么我可以将场景 1 中 tomcat 池中的线程数增加相同的数量”

最佳答案

要在这种情况下看到异步的优势,您需要使您的服务也异步。它不会执行占用线程的 sleep ,而是在安排三秒后完成时运行某些内容后立即返回。在这种情况下,所有请求将在三秒多一点的时间内完成;您的吞吐量为每秒 133 个请求,平均响应时间为三秒。如果您将线程计数调低,您将获得基本相同的响应时间。

异步的要点是,空闲等待 I/O 的线程可以立即空闲下来执行其他操作,因此您不必使用尽可能多的线程(这是一种昂贵的资源)来满足您的工作负载。

关于Java - 异步 - 线程池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42912521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com