springboot 注解@Async实现异步调用

冷不防 2023-02-08 12:41 73阅读 0赞

文章目录

      • 1.模拟业务方法 并添加注解@Async
      • 2.在启动类增加@EnableAsync注解
      • 3.测试类与接口一
      • 4.结果比较
      • 5.使用AsyncResult接收异步执行结果
      • 6.测试类与接口二
      • 7.总结

1.模拟业务方法 并添加注解@Async

  1. @Service
  2. public class TaskService {
  3. private static final Random random = new Random();
  4. @Async
  5. public void task1() {
  6. System.out.println("run task1 start...");
  7. long start = System.currentTimeMillis();
  8. try {
  9. Thread.sleep(random.nextInt(10000));
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println("run task1 end..., time: " + (System.currentTimeMillis() - start) + " ms");
  14. }
  15. @Async
  16. public void task2() {
  17. System.out.println("run task2 start...");
  18. long start = System.currentTimeMillis();
  19. try {
  20. Thread.sleep(random.nextInt(10000));
  21. } catch (InterruptedException e) {
  22. e.printStackTrace();
  23. }
  24. System.out.println("run task2 end..., time: " + (System.currentTimeMillis() - start) + " ms");
  25. }
  26. @Async
  27. public void task3() {
  28. System.out.println("run task3 start...");
  29. long start = System.currentTimeMillis();
  30. try {
  31. Thread.sleep(random.nextInt(10000));
  32. } catch (InterruptedException e) {
  33. e.printStackTrace();
  34. }
  35. System.out.println("run task3 end..., time: " + (System.currentTimeMillis() - start) + " ms");
  36. }
  37. }

2.在启动类增加@EnableAsync注解

  1. @SpringBootApplication
  2. @EnableAsync
  3. public class DemoApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(DemoApplication.class, args);
  6. }
  7. }

3.测试类与接口一

  1. @RestController
  2. public class TestAsyncController {
  3. @Autowired
  4. private TaskService taskService;
  5. @GetMapping("test/async/task")
  6. public void testAsyncTask() {
  7. long start = System.currentTimeMillis();
  8. taskService.task1();
  9. taskService.task2();
  10. taskService.task3();
  11. System.out.println("run all task end: " + (System.currentTimeMillis() - start) + " ms");
  12. }
  13. }

4.结果比较

  1. // task任务不加 @Async 的日志打印
  2. run task1 start...
  3. run task1 end..., time: 3739 ms
  4. run task2 start...
  5. run task2 end..., time: 8025 ms
  6. run task3 start...
  7. run task3 end..., time: 9057 ms
  8. run all task end: 20821 ms
  9. // task任务加 @Async 的日志打印 主任务先结束
  10. run all task end: 4 ms
  11. run task1 start...
  12. run task2 start...
  13. run task3 start...
  14. run task3 end..., time: 1095 ms
  15. run task2 end..., time: 4952 ms
  16. run task1 end..., time: 8442 ms

5.使用AsyncResult接收异步执行结果

  1. @Service
  2. public class TaskService {
  3. private static final Random random = new Random();
  4. @Async
  5. public Future<String> task1() {
  6. System.out.println("run task1 start...");
  7. long start = System.currentTimeMillis();
  8. try {
  9. Thread.sleep(random.nextInt(10000));
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println("run task1 end..., time: " + (System.currentTimeMillis() - start) + " ms");
  14. return new AsyncResult<>("task1 result");
  15. }
  16. @Async
  17. public Future<String> task2() {
  18. System.out.println("run task2 start...");
  19. long start = System.currentTimeMillis();
  20. try {
  21. Thread.sleep(random.nextInt(10000));
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. System.out.println("run task2 end..., time: " + (System.currentTimeMillis() - start) + " ms");
  26. return new AsyncResult<>("task2 result");
  27. }
  28. @Async
  29. public Future<String> task3() {
  30. System.out.println("run task3 start...");
  31. long start = System.currentTimeMillis();
  32. try {
  33. Thread.sleep(random.nextInt(10000));
  34. } catch (InterruptedException e) {
  35. e.printStackTrace();
  36. }
  37. System.out.println("run task3 end..., time: " + (System.currentTimeMillis() - start) + " ms");
  38. return new AsyncResult<>("task3 result");
  39. }
  40. }

6.测试类与接口二

  1. @RestController
  2. public class TestAsyncController {
  3. @Autowired
  4. private TaskService taskService;
  5. @GetMapping("test/async/task")
  6. public void testAsyncTask() {
  7. long start = System.currentTimeMillis();
  8. Future<String> future1 = taskService.task1();
  9. Future<String> future2 = taskService.task2();
  10. Future<String> future3 = taskService.task3();
  11. while (true) {
  12. if (future1.isDone() && future2.isDone() && future3.isDone()) {
  13. System.out.println(future1.get());
  14. System.out.println(future2.get());
  15. System.out.println(future3.get());
  16. break;
  17. }
  18. TimeUnit.MICROSECONDS.sleep(500);
  19. }
  20. System.out.println("run all task end: " + (System.currentTimeMillis() - start) + " ms");
  21. }
  22. }

7.总结

  1. 使用@Async注解的方法task1 task2 task3是异步调用的
  2. 使用@Async在主任务先结束,但主任务需要获取task1 task2 task3的执行结果的场景中不适用,需要配合AsyncResult实现(查看AsyncResult的源码,会发现它实现了Future<T>)
  3. @Async所修饰的函数不要定义为static类型,这样异步调用不会生效

发表评论

表情:
评论列表 (有 0 条评论,73人围观)

还没有评论,来说两句吧...

相关阅读