SpringBoot定时器,定制方法启动时间

想要实现的业务场景是:
不同的商家可以设置商品秒杀时间,每次执行完第一个商家的秒杀后,会开始准备执行下一个离目前时间最近的商家秒杀任务。
核心:
设置多个不同时间只用执行一次的定时任务。


核心代码,自动获取数据库中距离当前时间最近的秒杀任务开始准备执行 。

package com.shop.core.secKill.util;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shop.core.secKill.entity.VO.Cron;
import com.shop.core.secKill.mapper.CronMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

import java.util.Date;

@Configuration
@EnableScheduling
public class CompleteScheduleConfig implements SchedulingConfigurer {

    @Autowired
    @SuppressWarnings("all")
    private CronMapper cronMapper;

    /**
     * 执行定时任务.
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        Cron cron1 = new Cron();//对数据进行缓存

        Runnable task=new Runnable() {
            /**
             * 要定时执行的方法
             */
            @Override
            public void run() {
                if (cron1.getId()!=null){
                    System.err.println("cron1.getId()=="+cron1.getId());
                }else {
                    System.err.println("cron.getId()==null");
                }
            }
        };

        Trigger trigger=new Trigger() {
            /**
             * 调度实现的时间控制
             */
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                QueryWrapper<Cron> cronQueryWrapper = new QueryWrapper<>();//设置获取条件,每次获取最新的秒杀
                cronQueryWrapper.orderByAsc("date");
                cronQueryWrapper.last("limit 1");
                Cron cron = cronMapper.selectOne(cronQueryWrapper);//gou
                System.out.println("cron_id: "+cron.getId());
                cron1.setNum(cron.getNum());
                cron1.setGid(cron.getGid());
                cron1.setId(cron.getId());
                CronTrigger cronTrigger=new CronTrigger(cron.getCron());
                cronMapper.deleteById(cron.getId());//删掉,让下一次更新最新的
                return cronTrigger.nextExecutionTime(triggerContext);
            }
        };
        //设置定时任务             //执行方法   //调用时间
        taskRegistrar.addTriggerTask(task, trigger);
    }
}

run()方法中可以调用别的方法,这里的只需要把参数传递出去即可;


以下为数据库以及插入修改内容的方法(根据自己需要自行修改)
在这里插入图片描述
在这里插入图片描述

 /**
     * 添加|修改秒杀任务
     * @param secKillVO
     * @return ResponseData<Object> 自己写的一个返回类型
     */
    @Override
    public ResponseData<Object> setSecKill(SecKillVO secKillVO, HttpServletRequest request){
        final String[] s = secKillVO.getDate().toString().split(" ");
        System.out.println(s[0]);
        System.out.println(s[1]);
        final String[] date = s[0].split("-");
        final String[] time = s[1].split(":");
        String mon = date[1];
        String day = date[2];
        String hour = time[0];
        String min = time[1];
        String sec = time[2];
        final String sec1 = StringUtils.substring(sec, 0, 2);
        String str_time = sec1+" "+min+" "+hour+" "+day+" "+mon+" ?";//设置的秒杀时间
        Cron cron = new Cron();
        try {
            cron.setCron(str_time);
            cron.setGid(secKillVO.getGoodsId());
            cron.setNum(secKillVO.getNum());
            cron.setDuring(secKillVO.getDuring());
            cron.setDate(secKillVO.getDate());
            final User loginUser = loginService.getLoginUser(request);//获取当前商户id
            cron.setShopId(loginUser.getId());
            final Cron gid = cronMapper.selectOne(WrapperUtils.getQueryWrapper("gid", secKillVO.getGoodsId()));
            if (gid==null){//如果为空就添加秒杀,不为空就更新一下秒杀
                cronMapper.insert(cron);
                return Result.success("添加秒杀成功");
            }
            cronMapper.update(cron,WrapperUtils.getQueryWrapper("gid", secKillVO.getGoodsId()));
            return Result.success("修改秒杀成功");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("添加秒杀失败");
        }
    }


上诉的代码定时器启动之后并不能实现手动的开启关闭

package com.shop.core.secKill.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.concurrent.ScheduledFuture;

/**
 * 利用线程池实现任务调度
 * Task任务调度器可以实现任务的调度和删除
 * 原理:
 * 实现一个类:ThreadPoolTaskScheduler线程池任务调度器,能够开启线程池进行任务调度
 * ThreadPoolTaskScheduler.schedule()方法会创建一个定时计划ScheduleFuture,
 * 在这个方法中添加两个参数一个是Runable:线程接口类,和CronTrigger(定时任务触发器)
 * 在ScheduleFuture中有一个cancel可以停止定时任务
 * @author Admin
 *
 * Scheduled Task是一种轻量级的任务定时调度器,相比于Quartz,减少了很多的配置信息,但是Scheduled Task
 * 不适用于服务器集群,引文在服务器集群下会出现任务被多次调度执行的情况,因为集群的节点之间是不会共享任务信息的
 * 每个节点的定时任务都会定时执行
 *
 */
@RestController
@EnableScheduling
public class DynamicTaskController {
    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    private ScheduledFuture future;

    @Bean
    public ThreadPoolTaskScheduler trPoolTaskScheduler(){
        return new ThreadPoolTaskScheduler();
    }
    /**
     * 1,定义一个方法实现定时任务的启动
     * 2,定义一个方法实现用于终止定时任务
     * 3,修改定时任务时间:changeCron
     */
    /**
     * 启动定时器
     * @return
     */
    @RequestMapping("startTest")
    public String StartTest(){
        /**
         * task:定时任务要执行的方法
         * trigger:定时任务执行的时间
         */
        future=threadPoolTaskScheduler.schedule(new myRunable(),new CronTrigger("0/5 * * * * *") );

        return "startTest";
    }

    /**
     * 停止定时任务
     * @return
     */
    @RequestMapping("endTask")
    public String endTask(){
        if(future!=null){
            future.cancel(true);
        }
        System.out.println("endTask");
        return "endTask";
    }

    /**
     * 改变调度的时间
     * 步骤:
     * 1,先停止定时器
     * 2,在启动定时器
     */
    @RequestMapping("changeTask")
    public String changeTask(){
        //停止定时器
        endTask();
        //定义新的执行时间
        future=threadPoolTaskScheduler.schedule(new myRunable(),new CronTrigger("0/10 * * * * *") );
        //启动定时器
//        StartTest();
        System.out.println("changeTask");
        return "changeTask";
    }

    /**
     * 定义定时任务执行的方法
     * @author Admin
     *
     */
    public class myRunable implements Runnable{
        @Override
        public void run() {
            System.out.println("定时任务要执行的方法111"+new Date());
        }

    }

}


补充一下别的秒杀

@Configuration      //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class testTime { //3.添加定时任务
//    @Scheduled(cron = "26 23 16 15 7 ?")//7月15号16点23分26秒
	@Scheduled(cron = "0/2 * * * * ?")//从任意时间的0s开始,每2s执行一次
    private void configureTasks() {
            System.err.println("执行静态定时任务时间: " + LocalDateTime.now());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值