SpringBoot异步任务(1)|(异步任务执行以及回调)
章节
第一章链接: SpringBoot异步任务(1)|(异步任务执行以及回调)
前言
异步任务在springboot中的使用
一、使用场景
项目中有一个导入数据的任务,导入数据耗时,因此采用异步任务的方式执行,,任务执行希望立马能更新任务状态
二、springboot添加异步任务
1.启动类中添加异步任务
启动类中增加@EnableAsync注解,开启异步任务。@EnableAsync注解会在springboot项目启动的时候开启一个线程词,默认参数如下:
默认核心线程数:8,
最大线程数:Integet.MAX_VALUE,
队列使用LinkedBlockingQueue,
容量是:Integet.MAX_VALUE,
空闲线程保留时间:60s,
线程池拒绝策略:AbortPolicy
默认的线程池存在很多问题,存在很多风险,可以自定义配置
spring:
task:
execution:
pool:
max-size: 6
core-size: 3
keep-alive: 3s
queue-capacity: 1000
thread-name-prefix: name
2.编写任务执行服务
任务执行服务提供两个方法,一个提交执行没有响应,第二个提交执行后等待任务执行完成,然后再更新状态
@Log4j2
@Component
public class LoadTaskExecutor {
@Async
public void execute(LoadTask task) {
log.info("LoadTask is executing run task:{}", task.getId());
task.run();
}
@Async
public void execute(LoadTask task, Runnable callback) {
synchronized (task.getGraphName()) {
log.info("Executing task: {}", task.getId());
task.run();
log.info("Executed task: {}, update status to db", task.getId());
callback.run();
}
}
}
LoadTask 类示例
@Log4j2
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LoadTask implements Runnable {
private String id;
private String graphName;
private String jobId;
private String fileId;
public LoadTask(LoadOptions options, GraphConnection connection,
FileMapping mapping) {
this.id = null;
this.graphName = StringUtils.isEmpty(connection.getGraph()) ? mapping.getGraphName() : connection.getGraph();
this.jobId = mapping.getJobId();
this.fileId = mapping.getId();
this.fileName = mapping.getName();
}
/**
* 运行任务
*/
@Override
public void run() {
//运行任务业务代码
log.info("映射任务运行完成:{}", this.id);
}
}
3.任务调度方法
1、springboot调用任务的方式
public LoadTask start(GraphConnection connection, FileMapping fileMapping) {
// 数据初始化以及准备工作 ...
//调用任务
this.taskExecutor.execute(task, () -> {
try {
this.updateStatus(task);
} catch (Exception e) {
log.error("任务执行完成更新任务状态异常:{}", e.getMessage());
}
});
this.runningTaskContainer.put(task.getId(), task);
return task;
}
总结
上面的方式实现了异步多线程执行的思想,大家可以参考该模式使用在设计场景中