美文网首页
Spring定时器两种实现与底层

Spring定时器两种实现与底层

作者: 笨鸡 | 来源:发表于2020-07-01 18:06 被阅读0次

注解方式

/**
 * Copyright (C), 2015-2020, XXX有限公司
 * FileName: ScheduledTest
 * Author:   CT
 * Date:     2020/7/1 16:57
 * Description: 定时器
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package org.ctgu.game.db.timer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 〈一句话功能简述〉<br>
 * 〈定时器〉
 *
 * @author CT
 * @create 2020/7/1
 * @since 1.0.0
 */
@Slf4j
@Component
public class ScheduledTest {

    public static DateTimeFormatter DateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    // 注解声明式使用 - 每五秒执行一次,不支持initialDelay
    @Scheduled(cron = "*/5 * * * * *")
    public void cron1() {
        log.info(String.format("[%s] - CronTask1触发...", DateFormat.format(LocalDateTime.now())));
    }

    // 注解声明式使用 - 禁止任务执行
    @Scheduled(cron = "-")
    public void cron2() {
        log.info(String.format("[%s] - CronTask2触发...", DateFormat.format(LocalDateTime.now())));
    }

    // 注解声明式使用 - 延迟一秒开始执行,延迟间隔为5秒
    @Scheduled(fixedDelay = 5000, initialDelay = 1000)
    public void fixedDelay1(){
        log.info(String.format("[%s] - FixedDelayTask1触发...", DateFormat.format(LocalDateTime.now())));
    }

    // 注解声明式使用 - spring-boot配置文件中process.task.fixedDelay=5000  process.task.initialDelay=1000
    @Scheduled(fixedDelayString = "${process.task.fixedDelay}", initialDelayString = "${process.task.initialDelay}")
    public void fixedDelay2(){
        log.info(String.format("[%s] - FixedDelayTask2触发...", DateFormat.format(LocalDateTime.now())));
    }

    // 注解声明式使用 - 延迟一秒开始执行,每隔5秒执行一次
    @Scheduled(fixedRate = 5000, initialDelay = 1000)
    public void fixedRate1(){
        log.info(String.format("[%s] - FixedRateTask1触发...", DateFormat.format(LocalDateTime.now())));
    }

    // 注解声明式使用 - spring-boot配置文件中process.task.fixedRate=5000  process.task.initialDelay=1000
    @Scheduled(fixedRateString = "${process.task.fixedRate}", initialDelayString = "${process.task.initialDelay}")
    public void fixedRate2(){
        log.info(String.format("[%s] - FixedRateTask2触发...", DateFormat.format(LocalDateTime.now())));
    }

}

编程方式 (如 排行榜每周一结算并发放奖励——每十五分钟刷新一次Rank)

/**
 * Copyright (C), 2015-2020, XXX有限公司
 * FileName: Main
 * Author:   CT
 * Date:     2020/7/1 16:44
 * Description: 测试
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package org.ctgu.game.db.test;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.FixedDelayTask;
import org.springframework.scheduling.config.FixedRateTask;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 〈一句话功能简述〉<br>
 * 〈测试〉
 *
 * @author CT
 * @create 2020/7/1
 * @since 1.0.0
 */
@Slf4j
public class Main {

    public static DateTimeFormatter DateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public static void main(String[] args) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();
        taskRun(taskScheduler);
//        fixedDelayRun(taskScheduler);
        fixedRateRun(taskScheduler);
    }

    public static void taskRun(ThreadPoolTaskScheduler taskScheduler) {
        String cronString = "0 0 0 ? * MON";
        CronTask cronTask = new CronTask(() -> 
            log.info(String.format("[%s] - CronTask触发Get Week Rank Result...", DateFormat.format(LocalDateTime.now()))), 
                    cronString);
        taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
    }

    public static void fixedDelayRun(ThreadPoolTaskScheduler taskScheduler) {
        FixedDelayTask fixedDelayTask = new FixedDelayTask(() -> {
            log.info(String.format("[%s] - FixedDelayTask触发...", DateFormat.format(LocalDateTime.now())));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 5000, 1000);
        Date startTime = new Date(System.currentTimeMillis() + fixedDelayTask.getInitialDelay());
        taskScheduler.scheduleWithFixedDelay(fixedDelayTask.getRunnable(), startTime, fixedDelayTask.getInterval());
    }

    public static void fixedRateRun(ThreadPoolTaskScheduler taskScheduler) {
        LocalDateTime now = LocalDateTime.now();
        int rate = 15;
        int plusTime = rate - (now.getMinute()) % rate;
        LocalTime startTime = LocalTime.of(now.getHour(), now.getMinute() + plusTime);
        LocalDateTime startDateTime = LocalDateTime.of(now.toLocalDate(), startTime);
        long startTimeStamp = startDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long initialDelay = startTimeStamp - System.currentTimeMillis();
        System.out.println(initialDelay);
        FixedRateTask fixedRateTask = new FixedRateTask(() ->
                log.info(String.format("[%s] - FixedRateTask触发Update RankData ...", DateFormat.format(LocalDateTime.now()))),
                1000 * 60 * rate, initialDelay);
        Date sTime = new Date(startTimeStamp);
        taskScheduler.scheduleAtFixedRate(fixedRateTask.getRunnable(), sTime, fixedRateTask.getInterval());
    }

}

fixedDelay与fixedRate区别

大致用示意字符串来表示如下(每个 T1, 或 T2 代表任务执行秒数(每次任务执行时间不定),假定 fixedRate 或 fixedDelay 的值是 5 秒,用 W 表示等待的数)

fixedRate:T1T1WWWT2.T2.T2WW.T3.T3.T3.T3.T3.T4.T4.T4.T4.T4.T4.T4T5T5WWWT6.T6........

fixedDelay:T1.T1.WWWWW.T2.T2.T2WWWWW.T3.T3.T3.T3.T3.WWWWW.T4.T4.T4.T4.T4.T4.T4.WWWWWT6.T6

相关文章

  • Spring定时器两种实现与底层

    注解方式 编程方式 (如 排行榜每周一结算并发放奖励——每十五分钟刷新一次Rank) fixedDelay与fi...

  • 架构师JavaEE高级知识点,符合您的口味,成就您的未来!

    SSM项目整合 Spring IOC AOP 底层原理与实战、Spring mvc 各大组件 实现原理与项目实战、...

  • @Cached 不生效

    Spring AOP简介与底层实现机制——动态代理[https://www.cnblogs.com/hublogs...

  • swift 定时器

    定时器的两种简单实现方式: 1.timer 2.GCD 上面两种方法以及实现简单的定时器,但是还有一个隐藏的问题,...

  • JavaScript03

    今日主要内容 DOM节点的增删改查与级联下拉列表实现 BOM与window对象 location对象 两种定时器 ...

  • RTOS基础(软定时器)

    软定时器原理与创建 问题概述 设计原理 设计实现 软定时器的启动与停止 设计原理 设计实现 软定时器的删除与状态查...

  • Spring之AOP之底层实现

    Spring之AOP之底层实现 静态代理实现 定义IStudnetService接口 定义StudentServi...

  • 定时器

    定时器在开发中经常使用的,下面说两种定时器的的实现。 1:使用 GCD实现 (防止按钮重复点击) 2:使用 RAC...

  • 5.4 Spring AOP架构

    Spring AOP的核心架构基于代理。ProxyFactory spring代理两种实现 JDK动态实现(spr...

  • Spring声明事务原理及核心源码分析

    上一篇 << >> Spring声明事务底层实现原理 Spring事务是基于AOP环绕通知和异常通知实现的Spri...

网友评论

      本文标题:Spring定时器两种实现与底层

      本文链接:https://www.haomeiwen.com/subject/olehqktx.html