0
点赞
收藏
分享

微信扫一扫

SpringBoot异步任务, 以及带返回值的异步任务(@Async 不起作用的原因)


第一部分: 无返回值异步任务

当没有加入异步任务的时候,我们创建一个service ,里面的方法需要等待3秒才能完成, controller层写一个测试方法调用时间返回的接口, 直接调用,

下面是service层代码部分


 



1. package com.zz.amqp1.service;
2.  
3. import org.springframework.stereotype.Service;
4.  
5. import java.util.Date;
6.  
7. /**
8. * Description: 异步任务测试类
9. * User: zhouzhou
10. * Date: 2018-08-28
11. * Time: 13:30
12. */
13. @Service
14. public class AsyncService {
15.  
16. public void doNoReturn(){
17. try {
18. // 这个方法执行需要三秒
19. Thread.sleep(3000);
20. System.out.println("方法执行结束" + new Date());
21. } catch (InterruptedException e) {
22. e.printStackTrace();
23. }
24. }
25. }

下面是controller层代码部分



1. package com.zz.amqp1.controller;
2.  
3. import com.zz.amqp1.service.AsyncService;
4. import org.springframework.beans.factory.annotation.Autowired;
5. import org.springframework.web.bind.annotation.RequestMapping;
6. import org.springframework.web.bind.annotation.RequestMethod;
7. import org.springframework.web.bind.annotation.RestController;
8.  
9. /**
10. * Description: 异步任务测试类
11. * User: zhouzhou
12. * Date: 2018-08-28
13. * Time: 13:33
14. */
15. @RestController
16. public class AsyncController {
17. @Autowired
18. private AsyncService asyncService;
19.  
20. @RequestMapping(value = "/hello",method = RequestMethod.GET)
21. public String testAsyncNoRetrun(){
22. long start = System.currentTimeMillis();
23. asyncService.doNoReturn();
24. return String.format("任务执行成功,耗时{%s}", System.currentTimeMillis() - start);
25. }
26. }

启动项目在, 浏览器中输入url :http://localhost:8080/hello

返回结果如下:

SpringBoot异步任务, 以及带返回值的异步任务(@Async 不起作用的原因)_异步任务

3000毫秒.接下来我们在方法上加上注解 @Async后, 重启项目, 刷新页面查看调用时间


 

1. @Async
2. public void doNoReturn(){
3. try {
4. // 这个方法执行需要三秒
5. Thread.sleep(3000);
6. System.out.println("方法执行结束" + new Date());
7. } catch (InterruptedException e) {
8. e.printStackTrace();
9. }
10. }

并且在主启动类上开启@EnableAsync的注解


 



1. @EnableAsync // 开启异步任务
2. @SpringBootApplication
3. public class Amqp1Application {
4.  
5. public static void main(String[] args) {
6. SpringApplication.run(Amqp1Application.class, args);
7. }
8. }

SpringBoot异步任务, 以及带返回值的异步任务(@Async 不起作用的原因)_System_02

测试完成, 异步任务如此简单,就这样.

第二部分:有返回值的异步任务

返回值用Futrue变量封装起来,下面是service层的代码


 



1. @Async
2. public Future<String> doReturn(int i){
3. try {
4. // 这个方法需要调用500毫秒
5. Thread.sleep(500);
6. } catch (InterruptedException e) {
7. e.printStackTrace();
8. }
9. // 消息汇总
10. return new AsyncResult<>(String.format("这个是第{%s}个异步调用的证书", i));
11. }

读取的时候,记得要批量读取不能单独读取, 下面是controller层的代码


 



1. @GetMapping("/hi")
2. public Map<String, Object> testAsyncReturn() throws ExecutionException, InterruptedException {
3. long start = System.currentTimeMillis();
4.  
5. Map<String, Object> map = new HashMap<>();
6. List<Future<String>> futures = new ArrayList<>();
7. for (int i = 0; i < 10; i++) {
8. Future<String> future = asyncService.doReturn(i);
9. futures.add(future);
10. }
11. List<String> response = new ArrayList<>();
12. for (Future future : futures) {
13. String string = (String) future.get();
14. response.add(string);
15. }
16. map.put("data", response);
17. map.put("消耗时间", String.format("任务执行成功,耗时{%s}毫秒", System.currentTimeMillis() - start));
18. return map;
19. }

在浏览器输入地址:http://localhost:8080/hi

结果如下: 耗时500多毫秒的意思代表,springboot自带异步任务线程池是小于10的大小的

一定要批量读取结果, 否则不能达到异步的效果!!

1、异步方法和调用类不要在同一个类中

2、注解扫描时,要注意过滤,避免重复实例化,因为存在覆盖问题,@Async就失效了

举报

相关推荐

0 条评论