SpringBoot杂谈

Spring Boot——@Scheduled实现定时任务

2019-02-02  本文已影响66人  Hi_JIAQI
1.目前较为流行的两种定时任务方式:

1.开源的第三方框架: Quartz 或者 elastic-job , 但是这个比较复杂和重量级,适用于分布式场景下的定时任务,可以根据需要多实例部署定时任务(相对而言会比较大型,重量)。

2.使用Spring提供的注解: @Schedule 。 如果定时任务执行时间较短,并且比较单一,可以使用这个注解。

2.简单小案例:

存在两种调度方式: 单线程和多线程

串行方式:

使用的注解: @Scheduled 和 @EnableScheduling

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
//@EnableAsync   //开启异步注解功能
@Component
//添加@EnableScheduling注解到入口类声明上面(也可以放在启动类上)
@EnableScheduling
public class ScheduledTest {
    //每60S执行一次 上一次
    //fixedRate 启动时间点之后 X秒执行一次
  //@Async告诉Spring这是一个异步方法
    @Scheduled(fixedRate = 60000)
    public void satartSix() {
        System.out.println("fixedRate测试:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

    //initialDelay 第一次延迟 X秒执行,之后按照fixedRate的规则每X秒执行
    @Scheduled(initialDelay = 60000, fixedRate = 60000)
    public void satartSix1() {
        System.out.println("initialDelay测试" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

    //fixedDelay上一次 结束时间点之后 每X秒执行一次
    @Scheduled(fixedDelay = 60000)
    public void satartSix2() {
        System.out.println("fixedDelay" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

   //关于cron 可以通过百度cron表达式在线生成网站去生成
    @Scheduled(cron = "0 */1 * * * ?")
    public void satartSix3() {
        System.out.println("cron" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}

可以看到四个定时任务都已经执行,并且使同一个线程中串行执行,如果只有一个定时任务,这样做肯定没问题,当定时任务增多,如果一个任务卡死,会导致其他任务也无法执行。

并行方式:

当定时任务很多的时候,为了提高任务执行效率,可以采用并行方式执行定时任务,任务之间互不影响,
只要实现SchedulingConfigurer接口就可以。

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 taskRegistrar) {
        //设定一个长度10的定时任务线程池
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
    }
}
3.个人小笔记:

1.spring的定时任务默认是单线程,若进行多任务执行可能会出现问题。

上一篇下一篇

猜你喜欢

热点阅读