首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程池如何“映射”到Spring中的未来执行?

线程池如何“映射”到Spring中的未来执行?
EN

Stack Overflow用户
提问于 2015-09-24 11:09:47
回答 1查看 1K关注 0票数 1

考虑一项守则:

代码语言:javascript
复制
@Autowired
private AsyncRestOperations restTemplate;

@RequestMapping("/abcd")
public CompletableFuture<Result> process(HttpRequest request) {
    convertListenableFutureToCompletableFuture(restTemplate.getForEntity("http://...", Result.class))
        .thenApply(/*Some logic here*/)
        .thenCompose(/*Some logic returns future*/)
}

在这里,我可以看到以下处理顺序:

  1. Spring接收对DispatcherServlet的请求。
  2. DispatcherServlet确定处理程序并将请求传递给它。
  3. 调用process方法
  4. restTemplate.getForEntity被称为。
  5. thenApply被称为
  6. thenCompose被称为
  7. CompletableFuture“返回”给DispatcherServlet (或其他Spring组件)

据我了解,1-37在同一个线程池中执行(对吗?)

但是使用什么线程(池)来执行点4-6

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-24 11:17:21

  • 1-3和7在同一个线程上执行(就像对4的调用一样)
  • 5,6在同一个线程上执行,这是提供CompletableFuture结果的同一个线程(在步骤4中,很可能不是调用restTemplate的同一个线程)。
  • AsyncRestOperations是一个接口,因此内部发生的事情将取决于底层实现。
  • 如果您使用的是not客户端,那么Rest调用将在NIO客户机的内部事件循环池上执行( 5&6可能不是您想要的--参见thenApplyAsync,后面跟着thenCompose)。
  • 您正在使用异步阻塞I/O Rest客户端&通常调用将在其配置的线程池中的线程上执行--不幸的是,您使用的类的默认行为不是配置线程池,而是每次使用一个新线程--参见下面--(这里在同一个线程上执行的5和6可能很好,甚至是最佳的)。

更新

基于更多信息:示例是使用AsyncRestTemplate,它是

Spring用于异步客户端HTTP访问的中心类。..。 注意:默认情况下,AsyncRestTemplate依赖于标准的JDK工具来建立HTTP连接。通过使用接受HttpComponents的构造函数,您可以切换到使用不同的HTTP库,如Apache、Netty和OkHttp。

AsyncRestTemplate使用Spring的SimpleAsyncTaskExecutor (当通过默认构造函数实例化时)

TaskExecutor实现,它为每个任务触发一个新线程,异步执行它。支持通过"concurrencyLimit“bean属性限制并发线程。默认情况下,并发线程的数量是无限的。 注意:此实现不重用线程!考虑一下线程池TaskExecutor实现,特别是用于执行大量短期任务。

后面的部分可能不是最优的,我将AsyncRestTemplate配置为使用您自己的线程池。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32759828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档