有什么理由在外部调用上使用Spring @Async

时间:2015-09-30 23:06:50

标签: java spring tomcat asynchronous

当@Async应用于进行外部调用的方法时,该Tomcat请求线程现在能够处理下一个传入请求。但是当外部服务返回时会发生什么?

如果使用相同的线程池,理论上当外部服务返回时,所有线程都可能忙,现在我们必须等待一个空闲线程 - 这意味着使用@Async实际上可以在这种情况下更慢。

我只想看看@Async的好处并确认我的理解。

2 个答案:

答案 0 :(得分:2)

本身调用@Async方法并不能释放Tomcat线程 - 你需要将它与例如DeferredResult<>AsyncContext / startAsync() - 然后异步方法将在一个单独的池中运行(可通过Spring配置),正如您所说,原始线程可以被释放来处理另一个请求。

如果你的Tomcat线程池正在处理其他生命周期较短的请求,这样就可以在等待你的慢速外部请求完成时处理这些请求中的许多请求,这显然是一个直接的好处。如果您的其他请求足够频繁和/或密集到足以使您的Tomcat线程池最大化,那么无论如何都会出现性能问题,是否存在异步线程。

另一方面,如果您的Tomcat请求线程始终只是异步触发这些外部调用,那么在您达到其他限制之前,您的Tomcat池不太可能会耗尽。这种情况下的优点是,您可以并行处理多于Tomcat线程池中的线程的请求。

以上所有假设您使用DeferredResult<>AsyncContext/startAsync()等来释放Tomcat线程,但即使您没有这样做,仍然存在{{1}的情况可能很有用,例如

  • 您希望制作多个可以并行运行的外部请求,这些请求可能需要很长时间才能执行 - 请参阅Spring guides
  • 中的GitHub API示例
  • 您在本地执行了一些重要的处理,您的外部请求可以与此并行执行。在这种情况下,您将关闭@Async请求,然后执行本地工作,然后等待请求完成。

答案 1 :(得分:0)

据我了解,@Async方法将在新线程中运行。在外部服务返回之前,新线程将保持占用状态。因此,如果您的池缺少线程,则会在调用该方法时产生影响,并且请求将挂起,直到找到一个空闲线程。

所有这些都可以通过记录Thread.currentThread().getName()来验证。

是的,如果缺少免费线程,@Async就没有任何好处。解决方案是增加池中的线程数。