微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Boot REST - 将 ThreadPoolTask​​Executor 用于单个作业

如何解决Spring Boot REST - 将 ThreadPoolTask​​Executor 用于单个作业

我加入了公司的一个新团队,我看到他们广泛使用“ThreadPoolTask​​Executor”。它基本上是前端的后端 REST 应用程序,它调用其他 SOAP API 并将结果返回给客户端 - 只是一个传递。 99% 的情况下,每个 REST 端点仅调用单个 SOAP API 并将响应以 json 格式返回给客户端。然而,虽然它只是一个单一的 SOAP 调用,但它们使用了“ThreadPoolTask​​Executor”并调用了 .get() 阻塞方法

ThreadPoolTask​​Executor @Bean@Configuration 类上:

@Bean(name=“soapAsyncExecutor")
@Qualifier("soapAsyncExecutor")
   public ThreadPoolTaskExecutor getSoapAsyncExecutor() {
    final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    final ThreadFactory customThreadfactory = new ThreadFactoryBuilder()
        .setNameFormat(“SoapExecutor-%d")
        .setUncaughtExceptionHandler(uncaughtExceptionHandler())
        .setDaemon(true)
        .build();
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.setCorePoolSize(80);
    executor.setMaxPoolSize(200);
    executor.setQueueCapacity(80);
    executor.setKeepAliveSeconds(60);
    executor.setAllowCoreThreadTimeOut(true);
    executor.setThreadFactory(customThreadfactory);
    executor.afterPropertiesSet();
    return executor;
   }

@Service 上的代码

@Async("soapAsyncExecutor")
@Override
public Future<OrderInfo> getorderInfoAsync(final String orderId) {
    return new AsyncResult<OrderInfo>(this.getorderInfo(orderId);
}

private OrderInfo getorderInfo(final String orderId) {
    // return result from SOAP call which typically take 1 second
}

然后从 @RestController 上面这样调用异步方法

@GetMapping(value = "/order/{orderId}")
public OrderInfo getorderInfo(@PathVariable("orderId") final String orderId) {
   OrderInfo orderInfo = orderService.getorderInfoAsync(orderId).get();
   return orderInfo;
}

据我所知,Spring 中对 REST 端点的每个请求,无论如何都会启动一个新线程(由于我没有更好的词,我们将其称为主线程)。并在那里调用“.get()”方法会阻塞主线程。我的问题是,在这个封锁期间,

  1. 主线程的官方状态是什么——“阻塞”还是“等待”?如果被阻塞,对单个作业使用这样的“ThreadPoolTask​​Executor”是否有丝毫好处,因为它无论如何都会阻塞主线程?
  2. 是否可以通过任何方式调整此代码以带来好处,还是在 RestController 端点内为这样的单个作业使用异步编程毫无意义?

解决方法

主线程的官方状态是什么——“阻塞”或“等待”?

已阻止。

如果被阻塞,对于单个作业使用这样的“ThreadPoolTask​​Executor”是否有丝毫好处,因为它无论如何都会阻塞主线程?

没有。空无一人。事实上,我敢打赌将任务分派到线程池会带来额外的开销。不过,如果端点要等待多个任务完成,这是有道理的。

可以以任何方式调整此代码以带来好处,还是在 RestController 端点内为单个作业使用异步编程毫无意义?

当然。这是an example。这是another one。本质上,在您的场景中,只需返回 CompletableFuture 而不是调用 .get()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?