最近,后台需要做一些不同任务的定时任务。这里记录一下写的公共方法。
当我们的后台可能需要定时对某项任务进行定时操作,或者多个任务进行定时操作,这时候就要做一个公共的定时任务执行方法。
说一下我的解决办法:
首先,需要数据库新建一个定时任务的任务表,(字段就是时间,任务类型,任务状态等)
其次,需要写一个定时任务工具类,下面直接贴出代码:
定时任务线程工具类
public class ScheduleUtil {
private static ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
private static Map<String, ScheduledFuture<?>> scheduledFutureMap = new HashMap<>();
static {
//根据实际需要设置池子大小,避免池子过小导致线程阻塞无法执行,池子过大资源浪费
threadPoolTaskScheduler.setPoolSize(20);
threadPoolTaskScheduler.initialize();
System.out.println("定时任务线程池启动");
}
/**
* 启动
*
* @param scheduleTask 定时任务
* @param corn 执行时间表达式
*/
public static boolean start(ScheduleConfigTask scheduleTask, String corn) {
System.out.println("启动定时任务线程 taskId " + scheduleTask.getId());
ScheduledFuture<?> scheduledFuture = threadPoolTaskScheduler
.schedule(scheduleTask, new CronTrigger(corn));
scheduledFutureMap.put(scheduleTask.getId(), scheduledFuture);
return true;
}
/**
* 取消
*
* @param scheduleTask 定时任务
*/
public static boolean cancel(ScheduleConfigTask scheduleTask) {
System.out.println("关闭定时任务线程 taskId " + scheduleTask.getId());
ScheduledFuture<?> scheduledFuture = scheduledFutureMap.get(scheduleTask.getId());
if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
scheduledFuture.cancel(false);
}
scheduledFutureMap.remove(scheduleTask.getId());
return true;
}
/**
* 修改
*
* @param scheduleTask 定时任务
* @param corn 执行时间表达式
*/
public static boolean reset(ScheduleConfigTask scheduleTask, String corn) {
//先取消定时任务
cancel(scheduleTask);
//然后启动新的定时任务
start(scheduleTask, corn);
return true;
}
}
@Component
public class ScheduledTasks {
private final Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
// 定时任务开关,测试方便关闭
private Boolean flag = Boolean.TRUE;
/**
* 应用统计定时任务
* @Scheduled(cron = "40 * * * * ?")
* 1、5分钟
*/
@Scheduled(cron = "0 0/20 * * * *")
public void outTime() {
ScheduleUtil.reset(new ScheduleConfigTask(ScheduleType.APPUPDOWN,Integer.valueOf(split[1]),loanApp,loanApp.getAppName()+Integer.valueOf(split[1]),service),s.getCron());
}
/**
* 定时任务线程类
*/
@Data
public class ScheduleConfigTask implements Runnable{
private static final int TIMEOUT = 30000;
private Integer type;//定时任务类型
private Integer upDownFlag;//功能私有参数
private GtPush dto;//功能私有参数
private LoanApp loanApp;//功能私有参数
private String id;//定时任务唯一id
private TaskService service;
public ScheduleConfigTask(Integer type, GtPush dto, String id, TaskService service) {
this.type = type;
this.dto = dto;
this.id = id;
this.service = service;
}
public ScheduleConfigTask(Integer type, Integer upDownFlag, String id, TaskService service) {
this.type = type;
this.upDownFlag = upDownFlag;
this.id = id;
this.service = service;
}
public ScheduleConfigTask(Integer type, Integer upDownFlag, LoanApp loanApp, String id, TaskService service) {
this.type = type;
this.upDownFlag = upDownFlag;
this.loanApp = loanApp;
this.id = id;
this.service = service;
}
@Override
public void run() {
try {
//调用具体的任务方法
service.work(type,upDownFlag,dto,loanApp);
} catch (IOException e) {
e.printStackTrace();
}
}
}
具体功能service
public interface TaskService {
//void work(GtPush dto) throws IOException;
void work(Integer type, Integer upDownFlag, GtPush dto, LoanApp loanApp) throws IOException;
}
service实现类
@Service
public class TaskServiceImpl implements TaskService {
private final Logger logger = LoggerFactory.getLogger(TaskServiceImpl.class);
@Override
public void work(GtPush gtRequestDto) throws IOException {
//具体的执行功能
}
}
在测试调试期间,遇到一个问题,就是定时任务有时会执行,有人不会,经过一些调试后,发现定时任务失效的时间点同时有多个定时任务,而我的定时任务只有一个实例,就导致这个时间点的任务被阻塞超过定时时间而失效。
在池子初始化时加上大小的设置就可以了,设置合理的容量就可以了。
static {
//根据实际需要设置池子大小,避免池子过小导致线程阻塞无法执行,池子过大资源浪费
threadPoolTaskScheduler.setPoolSize(20);
threadPoolTaskScheduler.initialize();
System.out.println("定时任务线程池启动");
}
好了,暂时就这么多。
日拱一卒,得寸进尺。
本文介绍了如何在后台实现一个通用的定时任务管理方法,包括创建任务表、使用ThreadPoolTaskScheduler进行调度,并提供启动、取消和修改任务的工具类。在调试中遇到任务执行不一致的问题,通过调整线程池大小解决了任务阻塞问题,确保了定时任务的稳定执行。
1907

被折叠的 条评论
为什么被折叠?



