SpringBoot Scheduled 常见用法

外部统一管理可用 xxl-job ,将各定时任务集中管理,灵活改变执行频率,支持某一个定时器集群处理,避免多服务启动时,每个服务都执行(重复执行)

比如我的API服务里有一个定时任务,将API做成集群时,变成了 API1、API2、API3 ,这时候每个API都有定时任务。但我只能让一个执行,不能也没必要三个API都执行。就只能将定时任务独立成一个 应用发布,或者发布时只开启一个,另外两个不开启。

有了XXL-JOB,1、2、3只会轮训执行一次。

Spring 自带的 Schedule 用法 

@Component
@EnableScheduling
public class CronTask1 {
    Logger taskLogger = LoggerFactory.getLogger(this.getClass());

    /**
     * @Scheduled除过cron还有三种方式:fixedRate,fixedDelay,initialDelay
     * cron:表达式可以定制化执行任务,但是执行的方式是与fixedDelay相近的,也是会按照上一次方法结束时间开始算起。
     * fixedRate:控制方法执行的间隔时间,是以上一次方法执行完开始算起,如上一次方法执行阻塞住了,那么直到上一次执行完,并间隔给定的时间后,执行下一次。
     * fixedDelay:是按照一定的速率执行,是从上一次方法执行开始的时间算起,如果上一次方法阻塞住了,下一次也是不会执行,但是在阻塞这段时间内累计应该执行的次数,当不再阻塞时,一下子把这些全部执行掉,而后再按照固定速率继续执行。
     * initialDelay:initialDelay = 10000 表示在容器启动后,延迟10秒后再执行一次定时器。
     */
    @Scheduled(cron = "*/6 * * * * ?")
    public void crontabTask() {
        taskLogger.info("这是基于注解的方式的定时任务" + new Date());
    }

    //内部控制,可加条件判断是否要启用
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.addTriggerTask(() -> process(),
                triggerContext -> {
                    //每隔1分钟执行一次
                    String cron = "10,20 * * * * ?";
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                });
    }
    private void process() {
        String info = "这是基于接口的定时任务";
        System.out.println(info);
        taskLogger.info(info);
    }

}

多线程定时任务

@Component
@EnableScheduling
@EnableAsync
public class CronTask3 {
    Logger taskLogger = LoggerFactory.getLogger("crontabTask_3");

    @Async
    @Scheduled(fixedDelay = 10000)  //间隔10秒
    public void first() throws InterruptedException {
        System.out.println("第一个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
        taskLogger.info("第一个基于注解设定多线程定时任务");
        Thread.sleep(1000 * 10);
    }

    @Async
    @Scheduled(fixedDelay = 20000)
    public void second() {
        System.out.println("第二个定时任务开始 : " + LocalDateTime.now().toLocalTime() + "\r\n线程 : " + Thread.currentThread().getName());
        taskLogger.info("第二个基于注解设定多线程定时任务");

    }
}

 

posted @ 2021-12-31 09:33  VipSoft  阅读(287)  评论(0编辑  收藏  举报