在SpringBoot主程序中配置异步任务支持
配置@EnableAsync
/**
* 主程序
* @author FoneyXu
*/
@SpringBootApplication
@EnableTransactionManagement
@EnableAsync //开启对异步任务的支持
public class WeMapApplication {
public static void main(String[] args) {
SpringApplication.run(WeMapApplication.class, args);
System.out.println("程序启动成功");
}
}
配置线程池
实现AsyncConfigurer接口
/**
* 线程池配置
* @author FoneyXu
**/
@Configuration
public class ThreadPoolConfig implements AsyncConfigurer {
/**
*
* @Description: 获得线程池
* @author FoneyXu
*/
@Override
public Executor getAsyncExecutor() {
// 线程池
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 线程数
taskExecutor.setCorePoolSize(50);
// 最大线程数
taskExecutor.setMaxPoolSize(200);
// 线程队列最大线程数
taskExecutor.setQueueCapacity(1000);
// 初始化线程池
taskExecutor.initialize();
return AsyncConfigurer.super.getAsyncExecutor();
}
/**
*
* @Description: 处理异步线程中发生的异常
* @author FoneyXu
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
System.out.println("线程异常");
return AsyncConfigurer.super.getAsyncUncaughtExceptionHandler();
}
}
定义异步任务
异步方法必须使用@Async进行注解
@Component
public class MyTask {
Random random = new Random();
@Async
public ListenableFuture<String> task1() throws Exception {
System.out.println("线程" + Thread.currentThread().getName() + " 执行异步任务一");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("完成任务一,耗时:" + (end - start) + "毫秒");
return new AsyncResult<>("任务一完成");
}
@Async
public ListenableFuture<String> task2() throws Exception {
System.out.println("线程" + Thread.currentThread().getName() + " 执行异步任务二");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("完成任务二,耗时:" + (end - start) + "毫秒");
return new AsyncResult<>("任务二完成");
}
@Async
public ListenableFuture<String> task3() throws Exception {
System.out.println("线程" + Thread.currentThread().getName() + " 执行异步任务三");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("完成任务三,耗时:" + (end - start) + "毫秒");
return new AsyncResult<>("任务三完成");
}
}
测试
在Controller中调用异步任务,使用ListenableFuture的addCallback回调函数监听异步任务的执行情况,onSuccess表示任务执行成功,onFailure表示任务执行失败。
@Controller
public class AsyncController
@Autowired
private MyTask task;
@GetMapping("async")
@ResponseBody
public String testAsync() throws Exception{
System.out.println("当前线程" + Thread.currentThread().getName());
long start = System.currentTimeMillis();
System.out.println("任务开始:" + start);
//循环五次,分别调用任务一、二、三
for (int i = 0; i < 5; i++) {
ListenableFuture<String> task1 = task.task1();
ListenableFuture<String> task2 = task.task2();
ListenableFuture<String> task3 = task.task3();
task1.addCallback(new SuccessCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println("返回的结果是:" + result);
}
}, new FailureCallback() {
@Override
public void onFailure(Throwable ex) {
System.out.println("发生了异常:" + ex.getMessage());
}
});
task2.addCallback(new SuccessCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println("返回的结果是:" + result);
}
}, new FailureCallback() {
@Override
public void onFailure(Throwable ex) {
System.out.println("发生了异常:" + ex.getMessage());
}
});
task3.addCallback(new SuccessCallback<String>() {
@Override
public void onSuccess(String result) {
System.out.println("返回的结果是:" + result);
}
}, new FailureCallback() {
@Override
public void onFailure(Throwable ex) {
System.out.println("发生了异常:" + ex.getMessage());
}
});
}
return "成功" + System.currentTimeMillis();
}
}
测试效果
PS:在测试过程中,发现一个小情况,在MyTask中再定义一个异步任务allTask,allTask的作用是调用taskOne、taskTwo和taskThree,然后在Controller中直接调用allTask时,异步任务执行未成功。
@Async
public void allTask() throws Exception {
task1();
task2();
task3();
}