java 任务调度器

定时任务-Timer

一、什么是定时任务

        在项目开发过程中,经常会使用到定时任务。顾名思义,定时任务一般指定时执行的方法。例如,每天凌晨0点同步 A 系统的数据到 B 系统;每2小时统计用户的积分情况;每周一给支付宝用户推送上周收入支出数据报表等等。一般情况下,很多业务会定时在凌晨进行处理。因为这能避开用户使用高峰期,空闲时服务器资源充足,而且对用户影响小。

二、Timer使用方式

public class MyTask1 extends TimerTask {
    @Override
    public void run(){
        System.out.println("task1 run");
    }
}
public class MyTask2 extends TimerTask {
    @Override
    public void run(){
        System.out.println("task2 run");
    }
}
  public static void main(String[] args) {
     

        Timer timer = new Timer();
        延迟1秒启动,每1秒执行一次
        timer.schedule(new MyTask1(), 1000, 1000);
        timer.schedule(new MyTask2(), 2000, 2000);
    }

下面对schedule的重载方法进行说明:

1、在特定时间执行任务,只执行一次

public void schedule(TimerTask task,Date time)

2、在特定时间之后执行任务,只执行一次

public void schedule(TimerTask task,long delay)

3、指定第一次执行的时间,然后按照间隔时间,重复执行

public void schedule(TimerTask task,Date firstTime,long period)

4、在特定延迟之后第一次执行,然后按照间隔时间,重复执行

public void schedule(TimerTask task,long delay,long period)

5、第一次执行之后,特定频率执行,与3同

public void scheduleAtFixedRate(TimerTask task,Date firstTime,long period)

6、在delay毫秒之后第一次执行,后按照特定频率执行

public void scheduleAtFixedRate(TimerTask task,long delay,long period)

2. Spring Task

        Spring Task 是 Spring 框架的一个组件,它为任务调度提供了支持,使得开发者能够创建后台任务或定期执行的任务。通过 Spring Task,您可以方便地在 Java 应用程序中实现定时任务,比如每天凌晨进行数据同步、每小时执行一次清理操作等。

2.1 配置类启用定时任务支持

启动类添加@EnableScheduling注解,以开启基于注解的任务调度器。

默认情况下,系统会自动启动一个线程,调度执行项目中定义的所有定时任务。

@EnableScheduling
public class App {
}

2.2 同步定时任务

@Scheduled 定时任务

使用 Spring Boot 内置的注解方式,即在需要定时执行的方法上添加@Scheduled注解即可。定时执行的方法不能有参数,并且一般没有返回值,即使有返回值也没什么用。注意定时任务所在的类要作为 Spring Bean,在类上添加@Component注解即可。也就是说定时方法所在的类,你要放到IOC容器里面。

@Component
@Slf4j
public class ScheduledTask {

        //上一次开始执行时间和下次开始时间间隔5s
        @Scheduled(fixedRate = 5000)
        public void fixedRateTask() {
            log.debug("fixedRateTask");
        }

		//上次结束到下次开始执行时间间隔5s
        @Scheduled(fixedDelay = 5000)
        public void fixedDelayTask() {
               log.debug("fixedDelayTask");

        }
		//第一次延迟6秒后执行,然后每2s循环执行
        @Scheduled(initialDelay = 6000,fixedDelay = 2000)
        public void initialDelayTask() {
            log.debug("initialDelayTask");
        }

        //使用corn表达式每5s执行一次
        @Scheduled(cron = "0/5 * * * * ?")
        public void cron() {
              log.debug("cronTask执行");
        }      

}

使用@Scheduled注解形式的定时任务,默认是单个线程来执行项目中的所有定时任务的。即使如果同一时刻有两个定时任务需要执行,那么也只能其中一个定时任务完成之后再执行下一个定时任务。如果项目只有一个定时任务还好。如果定时任务增多时,如果一个任务被阻塞,则会导致其他任务无法正常执行。

若要改变这种行为,使得定时任务能够并发执行,可以配置任务调度线程池,来解决以上问题。首先配置一个线程池。

2.3 多线程(异步)定时任务

1.配置线程池

@Component
public class ExecutorConfig {
    //定义核心线程数
    public static final  int CORE_POOL_SIZE = 10;
    // 最大线程数
    public static final  int MAX_POOL_SIZE = 20;
    // 任务队列容量大小
    public static final  int QUEUE_MAX_COUNT = 100;

    @Bean("asyncScheduledPool")
    public Executor asyncScheduledPool(){
        //自定义线程池
        ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        threadPoolExecutor.setCorePoolSize(CORE_POOL_SIZE);
        //设置最大线程数 : 长工 +  临时工
        threadPoolExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        //设置任务队列容量大小
        threadPoolExecutor.setQueueCapacity(QUEUE_MAX_COUNT);
        //设置线程的名称前缀
        threadPoolExecutor.setThreadNamePrefix("myTask-");
        //设置拒绝策略
        threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        return  threadPoolExecutor;
    }

}

2.开启异步支持

要在 Spring Boot 应用中启用异步方法调用,需在启动类上添加 @EnableAsync 注解。

3.定义异步方法

在服务类中定义一个方法,并使用 @Async 注解标记它以实现异步执行:

2.4 Api说明

1. fixedDelay :上次结束到下次开始执行时间间隔:

@Scheduled(fixedDelay = 4000) 

2. fixedRate:上一次开始执行时间和下次开始时间间隔10s。如:

@Scheduled(fixedRate = 10000) 

3. initialDelay:第一次延迟多长时间后再执行。

@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次

4. cron

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值