Spring MVC框架 - 优化请求之异步方法的应用(Spring 的异步功能的使用)

  • 时间:2017-07-25
  • 分类:JSP/Java编程
  • 1624 人浏览
[导读]在我们的应用中,依然还有一个瓶颈。当用户搜索10 个关键字的时候,每个搜索都会串行执行。

在我们的应用中,依然还有一个瓶颈。当用户搜索10 个关键字的时候,每个搜索都会串行执行。我们可以通过使用不同的线程来快速提升应用的速度,让所有的搜索同时开始执行。
要启用Spring 的异步功能,必须要使用@EnableAsync 注解。这样将会透明地使用java.util.concurrent.Executor 来执行所有带@Async 注解的方法。
通过实现AsyncConfigurer 接口,可以自定义默认的执行器(executor)。我们在config 包中创建一个名为AsyncConfig 的新配置类:

借助这个配置,我们能够确保在应用中,用来处理异步任务的线程不会超过10 个。这对Web 应用来说是很重要的,因为每个客户端都会有一个专用的线程。你所使用的线程越多,阻塞时间越长,那么能够处理的客户端就会越少。
接下来,我们为搜索方法添加注解,使其变成异步方法。我们需要让它返回Future的一个子类型,这是Java 的一个并发类,代表了异步的结果。
我们创建TwitterSearch 类的一个新版本实现,它会在不同的线程中调用搜索API。实现类会有点复杂,因此我将其拆分为很小的组成部分来进行讲解。
首先,我们要为调用API 的方法添加@Async 注解,这样就会告诉Spring 要使用我们的执行器来调度该任务。同样,Spring 会使用代理来完成这项神奇的任务,因此这个方法要放到单独的一个类中,不能放到调用它的服务中。如果这个组件能够使用我们的缓存也是很不错的。所以,我们会按照如下的方式来创建这个组件:

先不要创建这个类,我们首先看一些服务的需求。
ListenableFuture 抽象允许我们在Future 完成的时候添加回调,不管得到正确的结果还是出现异常均会对它进行调用。
等待一批异步任务的算法可以写成如下的形式:

如果你不了解CountDownLatch 的话,可以将其理解为简单的阻塞队列。
await()方法将会一直等待,直到latch 达到0,从而解锁该线程。
前面的代码会为每个asynFetch 方法设置一个回调。这个回调会将结果添加到allTweets 列表中,并对latch 的计数进行递减。当所有的回调均被调用之后,这个方法就会返回所有的Tweet。
明白了吗?如下是完整的最终代码:

现在,要使用这个实现的话,我们需要基于async profile 来运行应用。
我们也可以同时使用多个profile,只需将它们用逗号分隔就可以了,如下所示:

如果我们搜索多个关键词的话,将会看到如下的效果:

这表示不同的搜索在并行执行。
Java 8 实际上引入了一个名为CompletableFuture 的新类型,它是操作Future 的更好的API。CompletableFuture 的主要问题在于,与它协作的所有执行器都要编写一些代码。这超出了本书的范围。关于这个话题,你可以查看我的博客:http://geowarin.github.io/spring/2015/06/12/completable-futures-with-spring-async.html。
tips:如果你之前不怎么喜欢JavaScript的话,更应如此,现在该学一下这门语言了。话又说回来,尽管WebSocket 非常酷,但它并不是强制要求掌握的。到这里,你可以安心地越过本章,看一下如何对应用进行部署。

qqbak.png

来源:本文为线上采编,如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除!