我在代码中使用 @Async
从 Rest Controller 对 3 个不同的方法进行 3 个并行调用。
根据我对 servlet 的理解(这可能是错误的),当 spring @RestController
方法收到请求时,会为其创建一个线程,从此以后,对于每个新请求,都会创建一个新线程创建。
已创建请求线程 1 - 3 异步线程
创建请求线程 2 - 3 个异步线程
现在 spring/Request 线程如何知道哪 3 个异步线程属于哪个线程,即请求线程 1 或请求线程 2。
可能有某种映射可以告诉他们。
我尝试在线搜索 @Async
但关于其工作的可用文档很少。 Google 充斥着如何使用代码但无法正常运行。
底线 - 有人可以向我解释一下 @Async
代码的工作/线程管理
更新图像以获得更好的解释:
1) 请求 1 进入并生成 3 个线程(A1、A2 和 A3),因为它是具有响应 R1、R2 和 R3 的异步调用。
2) 请求 2 进来并执行相同的操作,即请求:A4、A5 和 A6,响应为 R1、R2 和 R3..
3)现在我的问题是 R1 、 R2 和 R3 如何意识到它们是同一请求(即请求 1)的一部分。如果它是一个顺序调用,那么同一个线程将从头传播到结束。但是创建 6 个异步请求后,我在线程转储中只能看到 6 个线程,没有看到请求 1 或请求 2 的线程。
那么,在完成 R1、R2 和 R3 时,请求 1 如何完成但在完成 R1、R2 和 R6 时则不然 请求 1 从 R1 、R2 和 R 完成的记录保存在谁以及在哪里? R3。
最佳答案
例如,我们采用 Spring's tutorial 中的 findUser
方法
@Async
public CompletableFuture<User> findUser(String user) throws InterruptedException {
logger.info("Looking up " + user);
String url = String.format("https://api.github.com/users/%s", user);
User results = restTemplate.getForObject(url, User.class);
// Artificial delay of 1s for demonstration purposes
Thread.sleep(1000L);
return CompletableFuture.completedFuture(results);
}
假设您使用@EnableAsync
,每次调用findUser
实际上都会调用一个代理:
- 创建一个
CompletableFuture
实例。 - 在不同的线程中执行
findUser
,并传递相同的CompletableFuture
实例。- 执行完成后,它会更新共享的
CompletableFuture
实例。
- 执行完成后,它会更新共享的
- 将
CompletableFuture
返回给调用者。
线程池是在程序开始时创建的,代理从中获取线程来运行您的代码。
<小时/> The implementation位于AsyncExecutionInterceptor
类中,invoke
方法。
关于java - 线程管理/spring @Async 的工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44263530/