今天我在AsyncRestTemplate上做了一些实验。下面是一段示例代码:
ListenableFuture<ResponseEntity<MyObject[]>> result
= asyncRestTemplate.getForEntity(uri, MyObject[]);
List<MyObject> objects = Arrays.asList(result.get().getBody());
令我惊讶的是,请求没有在第一行发送到uri(即在调用getForEntity之后),而是在调用result.get()之后发送。
这不是一种同步的做事方法吗?
答案 0 :(得分:2)
执行异步请求的整个想法是,您不想等待异步任务启动/完成,或者您希望主线程在从Future实例请求结果之前执行其他任务。在内部,AsyncRestTemplate准备AsyncRequest并调用executeAsync方法。
AsyncClientHttpRequest request = createAsyncRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
ListenableFuture<ClientHttpResponse> responseFuture = request.executeAsync();
有两种不同的实现 - HttpComponentsAsyncClientHttpRequest
(使用Apache http component库中提供的高性能异步支持)和SimpleBufferingAsyncClientHttpRequest
(使用J2SE类提供的工具)。在HttpComponentsAsyncClientHttpRequest
的情况下,在内部它有一个线程工厂(不是Spring管理的AFAIK),而在SimpleBufferingAsyncClientHttpRequest
中,有一个Spring管理AsyncListenableTaskExecutor
的规定。重点是,在所有情况下都有一些ExecutorService
能够以异步方式运行任务。当然,这些线程池很自然,任务的实际开始时间是不确定的,取决于很多因素,如负载,可用的CPU等,不应该依赖。
答案 1 :(得分:0)
当您调用future.get()
时,您实际上是通过等待结果将异步操作转换为同步操作。
执行实际请求并不重要,重要的是因为它是异步的,除非/您需要结果,否则不需要担心它。
当您需要在处理结果之前执行其他工作,或者您根本不等待结果时,优势显而易见。