Spring定时任务

通过类上设置注解@EnableScheduling可以开启spring自带的定时任务,@Scheduled设置定时时间。还可以通过ThreadPoolTaskSchedulerschedule(Runable,cron)动态添加

使用

@Component
@EnableScheduling //定时任务
public class SchedulingTest{
     //每30秒执行一次
    @Scheduled(fixedRate = 1000 * 30)
    public void doSomeThing(){
           //没30秒输出一次
           System.out.println ("定时输出:" + dateFormat ().format (new Date ()));
    }

    //在固定时间执行(当时间匹配规则时输出)
    @Scheduled(cron = "0 */1 *  * * * ")
    public void reportCurrentByCron(){
        System.out.println ("固定时间输出" + dateFormat ().format (new Date()));
    }

     private SimpleDateFormat dateFormat(){
        return new SimpleDateFormat ("HH:mm:ss");
    }
}

固定时间匹配规则

字段 允许值 允许的特殊字符
0-59 , - * /
0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * ? / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * ? / L C #
空, 1970-2099 , - * /
  • 每个元素都可以是一个值如6,一个区间9-12 一个间隔时间8-18/4 /4代表间隔四个小时,一个列表1,3,5
  • 日期和星期互斥,即两个元素重合,必须其中一个设置?忽略
  • *代表所有可能的值
  • /指定数值的增量,如0/10(分钟单位中)代表0分钟开始,10分钟执行一次
  • ?仅在日期和星期中,代表不指定值
  • L用于日期和星期中,代表倒数第几个
  • W仅在日其中,代表平日(工作日)。15W代表离15号最近的一个工作日。
  • C日期,5C五个单位后的第一天
  • #每个月第几个星期几,例如在4#2表示某月的第二个星期三。

转换异步线程

单线程执行时间超过定时间隔可能会出现任务丢失的情况,可以使用异步线程避免这个问题。

  • 配置Spring@EnableAsync
  • 执行方法上配置任务线程池@Async
//每30秒执行一次
   @Async("taskExecutor")
   @Scheduled(fixedRate = 1000 * 3)
    public void xxx(){
        //...
    }

分布式情况下避免重复执行

  1. lock = redisTemplate.opsForValue().setIfAbsent(KEY, LOCK);采用Redis判断是否存在key,不存在则设置key,执行完成删除key的方式加锁(跨时区部署还是会重复执行)
  2. shedlock加锁
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
            <version>0.16.1</version>
        </dependency>

        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-jdbc-template</artifactId>
            <version>0.16.1</version>
        </dependency>

配置(jdbc),还有redis,mongo,zookeeper等锁的实现

@Configuration
@EnableScheduling
public class ShedlockConfig {

    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(dataSource);
    }

    @Bean
    public ScheduledLockConfiguration scheduledLockConfiguration(LockProvider lockProvider) {
        return ScheduledLockConfigurationBuilder
                .withLockProvider(lockProvider)
                .withPoolSize(10)
                .withDefaultLockAtMostFor(Duration.ofMinutes(10))//lock expire最大时间10分钟
                .build();
    }
}

shedlock表

CREATE TABLE shedlock(
    name VARCHAR(64),
    lock_until TIMESTAMP(3) NULL,
    locked_at TIMESTAMP(3) NULL,
    locked_by  VARCHAR(255),
    PRIMARY KEY (name)
)

加锁

 @Scheduled(fixedDelay = 10*1000 /**ms**/,initialDelay = 10*1000)
    @SchedulerLock(name = "demoLockTask", lockAtMostFor = 5*1000)
    public void checkTask(){
        LOGGER.error("checkTask executed");
    }

动态添加关闭定时任务

// 引入定时调度线程池
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler; 

// 接收线程调度返回的结果获取类
private ScheduledFuture<?> future;

public void test(){
    // 如果已经有任务了就取消原有任务
    if (future != null) {
           future.cancel(true);
       }
    // 每月第一天
    String cron = "0 0 0 1 * ?";
    future = threadPoolTaskScheduler.schedule(new MyRunnable(), new CronTrigger(cron));
    // Runnable也可以写成lambda
    future = threadPoolTaskScheduler.schedule(()->{
            //do..
        }, new CronTrigger(cron));
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354