Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程池是怎样的;“映射”;将来春天执行死刑?_Java_Multithreading_Spring_Spring Mvc_Asynchronous - Fatal编程技术网

Java 线程池是怎样的;“映射”;将来春天执行死刑?

Java 线程池是怎样的;“映射”;将来春天执行死刑?,java,multithreading,spring,spring-mvc,asynchronous,Java,Multithreading,Spring,Spring Mvc,Asynchronous,考虑一个代码: @Autowired private AsyncRestOperations restTemplate; @RequestMapping("/abcd") public CompletableFuture<Result> process(HttpRequest request) { convertListenableFutureToCompletableFuture(restTemplate.getForEntity("http://...", Result

考虑一个代码:

@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*/)
}
@Autowired
私有异步REST操作restTemplate;
@请求映射(“/abcd”)
公共CompletableFuture进程(HttpRequest请求){
ConvertListenableFutureTompleFuture(restTemplate.getForEntity(“http://...“,Result.class”)
.然后应用(/*此处有一些逻辑*/)
.thenCompose(/*某些逻辑返回future*/)
}
在这里,我可以看到以下处理顺序:

  • Spring接收到对DispatcherServlet的请求
  • DispatcherServlet
    确定处理程序并将请求传递给它
  • 调用过程方法
  • 调用restTemplate.getForEntity
  • 然后调用apply
  • 然后调用compose
  • CompletableFuture“返回”到DispatcherServlet(或其他Spring组件)
  • 据我所知,点
    1-3
    7
    是在同一线程池中执行的(对吗?)

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

    • 1-3和7在同一线程上执行(调用4也是如此)

    • 5,6在彼此相同的线程上执行,这是提供可完成的未来结果的同一线程(在步骤4中,很可能不是用于调用restTemplate的同一线程)

    • AsyncRestOperations是一个接口,因此内部发生的事情将取决于底层实现

    • 如果您使用的是NIO Rest客户机,Rest调用将在NIO客户机的内部事件循环池上执行(如5和6,这可能不是您想要的-请参阅ApplySync,然后是Compose)

    • 您使用的是异步阻塞I/O Rest客户端&通常调用将在其配置的线程池中的线程上执行-不幸的是,您使用的类的默认行为不是配置线程池,而是每次使用新线程-请参阅下文-(这里在同一个线程上执行5和6可能很好,甚至是最佳的)

    更新

    基于进一步的信息:示例使用AsyncRestTemplate,它是

    Spring的用于异步客户端HTTP访问的中心类。

    注意:默认情况下,AsyncRestTemplate依赖于标准JDK工具 建立HTTP连接。您可以切换到使用其他HTTP连接 通过使用 接受AsyncClientHttpRequestFactory的构造函数

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

    TaskExecutor实现,为每个任务启动一个新线程, 异步执行。支持限制并发线程 通过“ConcurrencyLit”bean属性 并发线程的数量是无限的

    注意:此实现不重用线程!请考虑 线程池TaskExecutor实现,尤其是 执行大量短期任务


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

    如果您发布RESTTemplatebean的配置(我们只能看到接口定义)调用步骤4后,应该可以准确地告诉您发生了什么。它只是SpringRESTAsync模板,它是这样创建的
    newAsyncRESTTemplate()
    。我在
    CompletableFuture
    中读到了
    *Async
    方法,但是我应该为它们使用什么
    Executor
    呢?spring是否为theseme提供了一个,或者我应该用线程池创建一个新bean,自动连接它并从中使用池?是的,我认为您必须使用一个spring管理的方法,因为另一个构造函数需要Spr正在初始化接口。例如,新的AsyncRestTemplate(新的ThreadPoolTaskExecutor());-它创建了一个非大小的线程池。有一个ThreadPoolExecutoryFactoryBean,可以用来以某种方式配置JDK ExecutorServices。@Cherry-在这种情况下,在CompletableFuture中不需要*Async方法。提交给a任务执行器比在同一线程上执行慢约10倍(对于标识函数应用程序)。因为您没有使用NIO,所以可以从异步Rest调用恢复线程。