gpt4 book ai didi

java - 在哪里创建 ExecutorServices 以及何时关闭它们

转载 作者:行者123 更新时间:2023-11-30 02:35:41 25 4
gpt4 key购买 nike

我正在使用 Spring 和 Jersey 创建 REST 服务,并且我有一个用例,对于收到的每个请求,我需要对上游 API 进行多次调用 (N)。

我收到一个请求,它有 n 个项目,对于每个项目,我创建一个线程来调用我的依赖项 (REST) 并处理响应。最后,我将所有响应收集在一起,保持顺序,并将它们作为单个响应返回给客户端。

我正在使用 Java 8 的 CompletableFuture,并且想知道我是否正确使用了 ExecutorService 框架。

@Component // automatic singleton by Spring
class A {
private ExecutorService executorService = Executors.newCachedThreadPool();

private RawResponse getRawResponse(Item item) {
// make REST call
}


private Response processResponse(RawResponse rawResponse) {
// process response
}

public List<Response> handleRequest(Request request) {
List<CompletableFuture> futureResponses = new ArrayList<>();

for(Item item : request.getItems()) {
CompletableFuture<Response> futureResponse = CompletableFuture.supplyAsync(() -> getRawResponse(item), executorService)
.thenApply(rawResponse -> processResponse(rawResponse))
.handle((response, throwable) {
if(throwable != null) { // log and return default response
} else { return response;}});

futureResponses.add(futureResponse);
}

List<Response> result = new ArrayList<>();

for (CompletableFuture<Resource> futureResponse : futureResponses) {
try {
result.add(futureResponse.get());
} catch (Exception e) {

// log error
}
}
return result;
}
}

我现在的问题是,我是否应该将 executorService 的创建移到上面:

List<CompletableFuture> futureResponses = new ArrayList<>();

并在上面调用 shutdown:

return result;

因为此时,我并没有真正在任何地方调用 shutdown,因为应用程序将始终在其 docker 容器中运行。

继续创建和丢弃池的成本是否高昂,或者当前的方式是否会泄漏内存?而且我认为将静态池调用为私有(private)字段 var 是多余的,因为该类无论如何都是一个 spring bean(单例)。

任何建议将不胜感激,我也应该使用cachedThreadPool吗?我不确定如何估算我需要的线程数。

最佳答案

should I move the creation of the executorService right above?

不,你没有,你的 ExecutorService 位于示例代码中的正确位置。将其视为一个线程池,您不会希望为 handleRequest 的每个方法调用初始化一个新的线程池并关闭它。当然ExecutorService比线程池做的事情更多,实际上它会在底层管理一个线程池,并为异步任务提供生命周期管理。

I am not really calling shutdown anywhere since the app will always run in it's docker container.

在大多数情况下,您会在应用程序启动时初始化 ExecutorService,并在应用程序关闭时关闭它。所以你可以把它留在那里,因为当应用程序退出时它会关闭,或者如果你需要正常关闭,你可以添加某种关闭 Hook

Is it costly to keep creating and discarding the pool.

有点,我们不想经常创建和丢弃Thread,所以我们有线程池,如果为每个方法调用创建/丢弃池,那么拥有线程有什么意义池。

or is the current way going to leak memory?

不需要,只要您提交的任务不泄漏内存即可。 ExecutorService本身的实现很好用。

And I think calling the pool static as a private field var is redundant since the class is a spring bean anyways (singleton)

是的,你是对的。如果您想要执行一些自定义的初始化过程,您还可以将 ExecutorService 定义为 Spring Bean 并将其注入(inject)到服务 bean 中。

should I be using a cachedThreadPool, I am not sure how to approximate the number of threads I need.

这很难说,您需要进行一些测试才能为您的应用程序获得正确的线程数。但大多数 NIO 或 EventDriven 框架的可用核心数默认是线程数的两倍。

关于java - 在哪里创建 ExecutorServices 以及何时关闭它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43174685/

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