首页 > 解决方案 > 如何通过调用 executorService.shutdownNow() 来停止 webclient get() exchange()?

问题描述

请告诉我如何解决这样的事情?虽然我试图中断通过 Spring WebFlux webClient 从 url 获取图像 - 它并没有停止。

我有下一个代码

method1(){
...
ExecutorService executor = Executors.newFixedThreadPool(3);

for (String url: urlList){
  executor.submit(
    () -> {

      //byte[] byteImage = getImage(url)

      //save in file system (byteImage)

      //save in DB (byteImage)

      //save in redis (byteImage)
    }
)}
...
}

  public byte[] getImage(String url) {


    byte[] result = null;

    try {
      webClient
          .get()
          .uri(url)
          .header("X-Requested-With", "XMLHttpRequest")
          .exchange()
          .flatMap(response -> {
            if (!response.statusCode().is2xxSuccessful()) {
              return Mono.error(new RuntimeException("Internal server error"));
            } else {
              return response.bodyToMono(ByteArrayResource.class);
            }
          }).map(ByteArrayResource::getByteArray)
          .block();
    } catch (Exception e) {
        log.warn("can't take screenshot {}", url);
    }

    return result;
  }

在另一个线程中,我尝试通过 executor.shutdownNow()

如果我删除 webClient #block() - 一切正常。所有线程成功中断,进程停止。

但是如果 webClient 有 block() 方法,则执行者不能停止执行。

请帮忙,我该如何解决这个问题?

标签: javainterruptexecutorservicespring-webclient

解决方案


我找到了解决方案。问题是当我捕捉到 InterruptedException 标志“中断”重置。另一个问题是当块抛出异常时,它会抛出包装的 InterruptedException

如果我尝试捕获并再次设置标志 InterruptedException 它没有进入条件,例如

if (e instanceof InterruptedException){
  Thread.currentThread().interrupt(); << this is never called
}

解决方案是:

if (Exceptions.unwrap(e) instanceof InterruptedException){
  Thread.currentThread().interrupt(); << this is never called
}

推荐阅读