利用spring自带的定时器 实现动态定时器的增删改

福兮祸所伏,祸兮福所倚

 简单业务场景:项目启动的时候 启动多个定时器,实现定时器的增删改。(走高速)


实现CommandLineRunner接口  并标记为spring组件(@Component)

@Component
public class ScheduleConfig implements CommandLineRunner {

    private static final Logger LOG = LoggerFactory.getLogger(ScheduleConfig.class);

    @Autowired
    MeterTaskService meterTaskService;

    @Autowired
    private CronTaskRegistrar taskRegistrar;

    @Autowired
    DeviceService deviceService;

    @Override
    public void run(String... args) throws Exception {
        LOG.debug("进入ScheduleConfig.....");
        List<MeterTask> meterTasks = meterTaskService.findAllCron();
        if (meterTasks.size() > 0) {
            for (MeterTask meterTask : meterTasks) {
                if (!meterTask.getIsSuccess()) {
                    // 每个定时器所对应的业务逻辑处理线程   
                    SchedulingRunnable task = new SchedulingRunnable(meterTask.getCron(), meterTask.getMeterId(), meterTaskService, deviceService);
                    // 将当前线程和标识以及cron表达式添加到CronTaskRegistrar中
                    taskRegistrar.addCronTask(meterTask.getMeterId(), task, meterTask.getCron());
                }
            }
        }
    }
}

看一下其中的taskRegistrar和SchedulingRunnable到底是什么鬼。

taskRegistrar

DisposableBean主要处理bean的  这里通过DisposableBean的destroy方法是销毁定时器

@Component
public class CronTaskRegistrar implements DisposableBean {

    // 线程安全map去存储定时器
    private final Map<Integer, ScheduledTask> scheduledTasks = new ConcurrentHashMap<>(16);

    @Autowired
    private TaskScheduler taskScheduler;

    // 添加定时器   cronId为定时器的唯一标识(根据你的业务去选择什么作为唯一标识)
    // task对应的线程   cronExpression为cron的表达式
    public void addCronTask(Integer cronId,Runnable task, String cronExpression) {
        addCronTask(cronId,new CronTask(task, cronExpression));
    }

    public void addCronTask(Integer cronId,CronTask cronTask) {
        if (cronTask != null) {
            if (this.scheduledTasks.containsKey(cronId)) {
                removeCronTask(cronId);
            }
            this.scheduledTasks.put(cronId, scheduleCronTask(cronTask));
        }
    }

    // 移除某个定时器
    public void removeCronTask(Integer cronId) {
        ScheduledTask scheduledTask = this.scheduledTasks.remove(cronId);
        if (scheduledTask != null) {
            scheduledTask.cancel();
        }
    }

    // 核心代码   
    public ScheduledTask scheduleCronTask(CronTask cronTask) {
        ScheduledTask scheduledTask = new ScheduledTask();
        scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
        return scheduledTask;
    }


    @Override
    public void destroy() throws Exception {
        for (ScheduledTask task : this.scheduledTasks.values()) {
            task.cancel();
        }
        this.scheduledTasks.clear();
    }
}

 SchedulingRunnable

/**
 * @author peanut
 */
public class SchedulingRunnable implements Runnable{

    private static final Logger LOG = LoggerFactory.getLogger(SchedulingRunnable.class);


    private String cron;

    private Integer meterId;

    private MeterTaskService meterTaskService;

    private DeviceService deviceService;

    public SchedulingRunnable(String cron, Integer meterId, MeterTaskService meterTaskService, DeviceService deviceService) {
        this.cron = cron;
        this.meterId = meterId;
        this.meterTaskService = meterTaskService;
        this.deviceService = deviceService;
    }

    @SneakyThrows
    @Override
    public void run() {
        // 执行任务
        System.out.println(meterId + "的表达式是:" + cron);
        System.out.println("执行任务");
        // 清零
        try {
            deviceService.clear(meterId + "");
        } catch (ConnectionException e) {
            LOG.error("当前的异常是:{}" + e.getMessage());
            throw new ConnectionException("请检查端口链接");
        } catch (Exception e) {
            throw new Exception("请检查端口链接");
        }

        // 如果是单次的话  就修改状态
        MeterTask meterTask = meterTaskService.findByMeterId(meterId);
        if (MeterConstant.BIT_ZERO_FLAG.equals(meterTask.getType())) {
            meterTaskService.updateByMeterId(meterId);
        }
    }
}
/**
 * @author peanut
 */
public final class ScheduledTask {
    public volatile ScheduledFuture<?> future;

    /**
     * 取消定时任务
     */
    public void cancel() {
        ScheduledFuture<?> future = this.future;
        if (future != null) {
            future.cancel(true);
        }
    }
}

代码很纯粹  很好理解   替换相关参数  可以直接拿去用 。

如果觉得有用的话  就可怜可怜小弟吧

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值