SpringBoot实战异步任务

2022-09-13 14:15:56

1. 简介

异步指的是每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

2. SpringBoot异步任务实现

2.1 实现一个简单的异步任务

步骤如下:

2.1.1 添加@EnableAsync注解,开启异步任务功能

@EnableAsync@SpringBootApplicationpublicclassUtilsApplication{publicstaticvoidmain(String[] args){SpringApplication.run(UtilsApplication.class, args);}}

2.1.2 定义异步任务

publicinterfaceAsyncService{Future<String>doTask1()throwsException;Future<String>doTask2()throwsException;Future<String>doTask3()throwsException;}
@ServicepublicclassAsyncServiceImplimplementsAsyncService{publicstaticRandom random=newRandom();@Async@OverridepublicFuture<String>doTask1()throwsException{System.out.println("开始做任务一");long start=System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end=System.currentTimeMillis();System.out.println("完成任务一,耗时:"+(end- start)+"毫秒");returnnewAsyncResult<>("任务一完成");}@Async@OverridepublicFuture<String>doTask2()throwsException{System.out.println("开始做任务二");long start=System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end=System.currentTimeMillis();System.out.println("完成任务二,耗时:"+(end- start)+"毫秒");returnnewAsyncResult<>("任务二完成");}@Async@OverridepublicFuture<String>doTask3()throwsException{System.out.println("开始做任务三");long start=System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end=System.currentTimeMillis();System.out.println("完成任务三,耗时:"+(end- start)+"毫秒");returnnewAsyncResult<>("任务三完成");}}

2.1.3 定义接口

@RestControllerpublicclassAsyncController{@AutowiredAsyncService asyncService;@RequestMapping("/async")publicStringgetEntityById()throwsException{long start=System.currentTimeMillis();Future<String> task1= asyncService.doTask1();Future<String> task2= asyncService.doTask2();Future<String> task3= asyncService.doTask3();while(true){if(task1.isDone()&& task2.isDone()&& task3.isDone()){// 三个任务都调用完成,退出循环等待break;}Thread.sleep(1000);}long end=System.currentTimeMillis();return"任务全部完成,总耗时:"+(end- start)+"毫秒";}}

2.1.4 结果

在这里插入图片描述

{"code":200,"message":"成功","data":"任务全部完成,总耗时:10006毫秒"}

2.2 使用自定义的线程池配置

@EnableAsync中的注释:

*Bydefault,Spring will be searchingfor an associated thread pool definition:* either a unique{@linkorg.springframework.core.task.TaskExecutor} bean in the context,* or an{@linkjava.util.concurrent.Executor} bean named"taskExecutor"otherwise. If* neither of the two is resolvable, a{@linkorg.springframework.core.task.SimpleAsyncTaskExecutor}* will be usedtoprocess async methodinvocations. Besides, annotated methods having a*{@codevoid}return type cannot transmit any exception backtothecaller. Bydefault,* such uncaught exceptions are only logged.

2.2.1 实现AsyncConfigurer接口

@Slf4j@ConfigurationpublicclassAsyncConfigimplementsAsyncConfigurer{@OverridepublicExecutorgetAsyncExecutor(){ThreadPoolTaskExecutor executor=newThreadPoolTaskExecutor();
         executor.setCorePoolSize(7);
         executor.setMaxPoolSize(42);
         executor.setQueueCapacity(11);
         executor.setThreadNamePrefix("MyExecutor-");
         executor.initialize();return executor;}/**
     * 异步任务中异常处理
     */@OverridepublicAsyncUncaughtExceptionHandlergetAsyncUncaughtExceptionHandler(){returnnewAsyncUncaughtExceptionHandler(){@OverridepublicvoidhandleUncaughtException(Throwable ex,Method method,Object... params){
                log.error("=========================="+ex.getMessage()+"=======================", ex);
                log.error("exception method:"+method.getName());}};}}

2.2.2 在AsyncServiceImpl中添加代码

System.out.println("当前线程:"+Thread.currentThread().getName());

2.2.3 结果

当前线程:MyExecutor-3 执行任务3
当前线程:MyExecutor-1 执行任务1
当前线程:MyExecutor-2 执行任务2
完成任务二,耗时:6734毫秒
完成任务一,耗时:7514毫秒
完成任务三,耗时:9308毫秒
{"code":200,"message":"成功","data":"任务全部完成,总耗时:10011毫秒"}
  • 作者:weixin_45773632
  • 原文链接:https://blog.csdn.net/weixin_45773632/article/details/123472298
    更新时间:2022-09-13 14:15:56