1 ThreadPoolTaskExecutor
使用 ThreadPoolTaskExecutor
可以实现一个 TaskExecutor
.
下面看个示例, 基于 ThreadPoolTaskExecutor
实现方法的异步调用.
写一个配置类 提供线程池:
@Configuration
@ComponentScan("cn.mitrecx.learn4advance.executor")
@EnableAsync // 开启异步任务支持
public class TaskExecutorConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(4);
taskExecutor.setMaxPoolSize(8);
taskExecutor.setQueueCapacity(16);
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
需要异步执行的 类/方法:
@Service
public class AsyncTaskService {
@Async // Async 注解说明该方法是一个异步方法
public void executeAsyncTask(Integer i) {
System.out.println("执行异步任务: " + i);
}
@Async
public void executeAsyncTask2(Integer i) {
System.out.println("执行异步任务2=====: " + i);
}
}
启动类:
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class);
for (int i = 0; i < 10; i++) {
asyncTaskService.executeAsyncTask(i);
asyncTaskService.executeAsyncTask2(i);
}
context.close();
}
执行结果:
执行异步任务: 0
执行异步任务2=====: 1
执行异步任务: 2
执行异步任务: 1
执行异步任务2=====: 0
执行异步任务2=====: 2
.....
可以看到, 被 @Async
注解的方法是异步执行的.
2 定时任务
@Scheduled
注解支持定时任务, 可选的参数主要有:
- fixedDelay, 指定任务执行的时间间隔(上一个任务结束到下一个任务开始的间隔)
- fixedRate, 指定任务执行的时间间隔(上一个任务开始到下一个任务开始的间隔, 若任务的执行时间X毫秒 超过了 fixedRate 毫秒, 那么下一个任务会在 X 毫秒后执行)
- cron, 指定具体的时间点, 比如 每天晚上10点执行.
示例代码如下.
直接在 需要定时执行的方法上加上 @Scheduled
注解即可:
@Service
public class ScheduledTaskService {
private static final SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedDelay = 5000)
public void reportCurrentTime() {
System.out.println("每隔5秒执行一次 " + df.format(new Date()));
try {
Thread.sleep(6000); // 每隔 11 秒执行一次
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Scheduled(cron = "0 28 11 ? * *") // 每天11点28分执行
public void fixTimeExecution() {
System.out.println("在指定的时间 " + df.format(new Date()) + " 执行");
}
}
配置类:
@Configuration
@ComponentScan("cn.mitrecx.learn4advance.scheduler")
@EnableScheduling
public class TaskSchedulerConfig {
}
主程序:
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(TaskSchedulerConfig.class);
}
源码.
Reference
[1]. Spring Boot 实战 - 汪云飞