springboot 异步任务

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot 异步任务相关的知识,希望对你有一定的参考价值。

发表于  | Spring框架 | SpringBoot

Spring 对异步任务具有很好的支持。这篇文章,我们透过 Spring Boot 来讲解下单发服务模式和请求应答模式。

Spring Boot 集成异步任务

在 Spring Boot 中使用 @EnableAsync 开启异步支持。

  1. @Configuration
  2. @EnableAsync
  3. public class AsyncConfig {
  4.  
  5. }

现在,我们在 Spring Boot 中,我们只需要通过使用 @Async 注解就能将原来的同步方法变为异步方法。

单发服务模式

多个服务之间逻辑上不存在相互依赖关系,执行先后顺序没有严格的要求,逻辑上可以被并行执行。对于单发服务只有请求,没有应答,很容易设计成异步的。发起服务调用后。立即返回,不需要同步阻塞等待应答。

  1. @Service
  2. public class MsgServer {
  3. @Async
  4. public void sendA() throws Exception {
  5. System.out.println("send A");
  6. Long startTime = System.currentTimeMillis();
  7. Thread.sleep(2000);
  8. Long endTime = System.currentTimeMillis();
  9. System.out.println("耗时:" + (endTime - startTime));
  10. }
  11.  
  12. @Async
  13. public void sendB() throws Exception {
  14. System.out.println("send B");
  15. Long startTime = System.currentTimeMillis();
  16. Thread.sleep(2000);
  17. Long endTime = System.currentTimeMillis();
  18. System.out.println("耗时:" + (endTime - startTime));
  19. }
  20. }

此时,因为我们添加了 @Async 注解,它就变成了异步方法。

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringApplicationConfiguration(classes = WebMain.class)
  3. public class AsyncTest {
  4.  
  5. @Autowired
  6. private MsgServer msgServer;
  7.  
  8. @Test
  9. public void test() throws Exception {
  10. msgServer.sendA();
  11. msgServer.sendB();
  12. }
  13. }

请求应答模式

对于,请求的内容,需要应答,例如我们需要在多个方法调用都完成后,才进行接下来的操作,此时我们可以利用 Java 的 Future-Listener 机制来实现异步服务调用。

  1. @Service
  2. public class MsgFutureServer {
  3. public static Random random = new Random();
  4.  
  5. @Async
  6. public Future<String> sendA() throws Exception {
  7. System.out.println("send A");
  8. Long startTime = System.currentTimeMillis();
  9. Thread.sleep(2000);
  10. Long endTime = System.currentTimeMillis();
  11. System.out.println("耗时:" + (endTime - startTime));
  12. return new AsyncResult<String>("success");
  13. }
  14.  
  15. @Async
  16. public Future<String> sendB() throws Exception {
  17. System.out.println("send B");
  18. Long startTime = System.currentTimeMillis();
  19. Thread.sleep(2000);
  20. Long endTime = System.currentTimeMillis();
  21. System.out.println("耗时:" + (endTime - startTime));
  22. return new AsyncResult<String>("success");
  23. }
  24. }

下面的单元测试,在等待完成两个异步任务后,再统计具体耗时时长。

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringApplicationConfiguration(classes = WebMain.class)
  3. public class AsyncFutureTest {
  4.  
  5. @Autowired
  6. private MsgFutureServer msgFutureServer;
  7.  
  8. @Test
  9. public void test() throws Exception {
  10. long startTime = System.currentTimeMillis();
  11.  
  12. Future<String> task1 = msgFutureServer.sendA();
  13. Future<String> task2 = msgFutureServer.sendB();
  14.  
  15. while(true) {
  16. if(task1.isDone() && task2.isDone() ) {
  17. break;
  18. }
  19. }
  20.  
  21. long endTime = System.currentTimeMillis();
  22. System.out.println("总耗时:" + (endTime - startTime));
  23. }
  24. }

源代码

相关示例完整代码: springboot-action

以上是关于springboot 异步任务的主要内容,如果未能解决你的问题,请参考以下文章

屏幕方向期间片段内的异步任务

#yyds干货盘点# springboot配置@Async异步任务的线程池

从片段中调用分离的异步任务类

Android 我应该在异步任务中将片段作为弱引用传递吗?

异步任务片段背景数据

我应该在 Fragment 中的啥生命周期状态下执行异步任务?