Spring Boot 使用HttpClient和sendAsync以及newFixedThreadPool时,Sprint-Boot应用程序不会结束

46qrfjad  于 2023-02-19  发布在  Spring
关注(0)|答案(1)|浏览(155)

当使用HttpClient(java .NET.http.HttpClient)来执行一些GET请求时,我希望使用固定线程池。
因此我用这个方法编写了一个spring-boot应用程序(用于测试):

public class AppStartupRunner implements ApplicationRunner {
  // ....
  private ExecutorService executorService = Executors.newFixedThreadPool(10);

  @Override
  public void run(ApplicationArguments args) throws Exception {
  
    HttpClient httpClient = HttpClient.newBuilder().executor(executorService).build();
    //HttpClient httpClient = HttpClient.newBuilder().build();
  
    String url = "https://<url>";
    try {
      httpClient
        .sendAsync(HttpRequest.newBuilder().uri(URI.create(url)).GET().build(), BodyHandlers.ofString())
        .thenApply(HttpResponse::body).get();
    } catch (
        Exception e) {
      e.printStackTrace();
    }
    
    System.out.println("Out");
  }
  // ....
}

我的问题是,当我运行这个应用程序的http调用完成,我收到我的数据。我也已经检查了“isDone”方法,它确认请求完成。但应用程序没有结束-我认为主线程结束了,但仍然有一个(或多个?)进程挂起/等待。
当我将httpClient替换为不使用我的executorService的httpClient时,应用程序正确结束。
有一点:当我让HttpClient使用executorService并在最后显式地关闭executorServer(--〉executorService.shutdown();)应用程序也正确结束。但是我不确定这是否是正确的解决方案,或者只是隐藏了一个问题。因为来自executorService的10个线程总是在运行(无论httpClient是否使用它们),所以我不知道如果使用了executorService,我需要关闭它,否则我不会...

9vw9lbht

9vw9lbht1#

正确的方法是在确认所有线程都已完成之后调用executorService.shutdown(),在调用shutdown()之前,10个线程仍然处于活动状态并等待。
毫无疑问,调用executorService.shutdown()之后,不能再向服务中添加新线程,我认为这在您的情况下是安全的,因为每次您的应用程序运行时,都会构建一个新的ExecutorService
您可以在文档中进一步阅读:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html

相关问题