使用Spring Boot 1.5.2.RELEASE
和@Async
注释似乎被忽略了。
设置如下环境:
@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("async-task-");
executor.initialize();
return executor;
}
...
...异步方法本身:
@Service
public class MyService {
@Async
public Future<Long> asyncTask() throws Exception {
Long test = 1023L;
Thread.sleep(10000);
return new AsyncResult<>(test);
}
}
...现在我正在尝试使用它:
@RestController
public MyController {
@Autowired
public MyService myService;
@PostMapping("/test")
public ResponseEntity<MyResponse> test() {
return new ResponseEntity<>(
new MyResponse(myService
.asyncTask()
.get()),
HttpStatus.OK);
}
}
...并且控制器方法仍然会挂起10sec
而不是立即返回。
从不同的对象调用@Async
方法。它在类似的问题中提到的既不是私人的也不是交易的。
如何让方法异步调用?
答案 0 :(得分:3)
您的test()函数正在调用Future实例上的get()。该函数的文档说明:“如果需要计算完成,则等待,然后检索其结果。”
因此,如果调用者可以使用ID来稍后检索结果(或切换到同步响应),那么您可能希望返回某种排序,而不是调用get()。
答案 1 :(得分:3)
你应该看一下 Future#get javadoc:
如果需要等待计算完成,然后检索 结果。
您正在通过调用get
方法将异步方法转换为同步调用。
因此,只需返回get
,而不是调用Future
。 Spring MVC支持future as return type:
ListenableFuture或CompletableFuture / CompletionStage可以 当应用程序想要从a生成值时返回 线程池提交。
示例:
return myService.asyncTask().thenApply(r -> ResponseEntity.ok(new MyResponse(r)));