后台可控--定时任务类型及数量

本文介绍了如何在后台实现一个通用的定时任务管理方法,包括创建任务表、使用ThreadPoolTaskScheduler进行调度,并提供启动、取消和修改任务的工具类。在调试中遇到任务执行不一致的问题,通过调整线程池大小解决了任务阻塞问题,确保了定时任务的稳定执行。

最近,后台需要做一些不同任务的定时任务。这里记录一下写的公共方法。
当我们的后台可能需要定时对某项任务进行定时操作,或者多个任务进行定时操作,这时候就要做一个公共的定时任务执行方法。
说一下我的解决办法:
首先,需要数据库新建一个定时任务的任务表,(字段就是时间,任务类型,任务状态等)
其次,需要写一个定时任务工具类,下面直接贴出代码:

定时任务线程工具类

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("定时任务线程池启动");
    }

好了,暂时就这么多。
日拱一卒,得寸进尺。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值