Springboot使用@Scheduled配置定时任务

Springboot使用@Scheduled配置定时任务

串行方式

使用的注解: @Scheduled
应用启动类添加注解:@EnableScheduling
代码示例:

package com.bin.kong.csdnspider.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class TestJob {
    @Scheduled(cron = "0/5 * * * * ?")
    public void exec() {
        log.info("Hello World!");
    }
}

打印日志如下:

2019-09-28 19:02:15.002 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!
2019-09-28 19:02:20.001 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!
2019-09-28 19:02:25.003 INFO 40178 — [ scheduling-1] com.bin.kong.csdnspider.job.TestJob : Hello World!

定时任务Cron配置可参考:https://www.cnblogs.com/linjiqin/archive/2013/07/08/3178452.html

并行执行

串行执行的时候,可能会出现线程阻塞导致执行延时的情况.
代码示例:

package com.bin.kong.csdnspider.job;

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

@Component
@Slf4j
public class TestJob {

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec() {
        try {
            Thread.sleep(1000*10);
            log.info("Hello World!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec2() {
        log.info("World Hello!" );
    }
}


结果打印,exec2的执行时间延时变成了15秒:
在这里插入图片描述

解决办法

1.使用线程池的方式:
配置方法可参考: Springboot线程池配置管理
代码示例:

package com.bin.kong.csdnspider.job;

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

@Component
@Slf4j
public class TestJob {

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec() {
        try {
            Thread.sleep(1000*10);
            log.info("Hello World!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0/5 * * * * ?")
    @Async("threadExecutor")
    public void exec2() {
        log.info("World Hello!" );
    }
}

2.使用Executors的方式

代码示例:

package com.bin.kong.csdnspider.job;

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

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
@Slf4j
public class TestJob {

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec() {
        try {
            Thread.sleep(1000 * 10);
            log.info("Hello World!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void exec2() {
        ExecutorService service = Executors.newFixedThreadPool(5);
        service.execute(() -> {
            log.info("World Hello!");
        });
    }
}

3.将Scheduled配置成多线程执行的方式
示例代码:

package com.bin.kong.csdnspider.job;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.Executors;

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
    }
}

参数列表
参数名描述
corn可以使用Cron表达式来配置定时任务
fixedRate该属性的含义是上一次调用开始后再次调用的延时(不用等待上一次调用完成)
fixedRateString含义同fixedRate,只是参数是String类型
fixedDelay该属性的含义是等一上次调用执行完成后再次调用的延时(需要等上一次调用完成)
fixedDelayString含义同fixedDelay,只是参数是String类型
initialDelay该属性的含义是第一次执行的延时,需配合fixedRate等其他参数使用
initialDelayString含义同initialDelay,只是参数是String类型
zone与cron配合使用,指定所使用的时区。若不设置,则使用当前时区。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值