springboot schedule

1、Spring Task

1.1、同一线程调度

(1)在主程序入口处添加如下注解

//@SpringBootApplication
@EnableScheduling
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
public class DemoApplication {

   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}

如上代码所示:@EnableScheduling的注解

(2)在对应的测试方法中添加对应的注解

  

 @Scheduled(fixedRate = 2000)
    public void test() {

        Thread thread = Thread.currentThread();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
        System.out.println("调度测试:" + "test----" +  format.format(new Date()) + "------>" + thread.getId());

    }

    @Scheduled(fixedRate = 2000)
    public void test1() {
        Thread thread = Thread.currentThread();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
        System.out.println("调度测试:" + "test1----" +  format.format(new Date()) + "----->" + thread.getId());

    }

如上代码所示:@Scheduled(fixedRate=2000),含义为每两秒调用一次,如下所示的日志打印所示:

调度测试:test----2018-43-24 16:43:56------>27

调度测试:test1----2018-43-24 16:43:56----->27

调度测试:test----2018-43-24 16:43:58------>27

调度测试:test1----2018-43-24 16:43:58----->27

调度测试:test----2018-44-24 16:44:00------>27

调度测试:test1----2018-44-24 16:44:00----->27

调度测试:test----2018-44-24 16:44:02------>27

调度测试:test1----2018-44-24 16:44:02----->27

调度测试:test----2018-44-24 16:44:04------>27

调度测试:test1----2018-44-24 16:44:04——>27

对于注解中的参数解释:

  • fixedRate:定义一个按一定频率执行的定时任务

  • fixedDelay: 定义一个按一定频率执行的定时任务,与上面不同的是,改属性可以配合initiaDelay, 定义该任务延迟执行时间

  • cron  : 通过表达式来配置任务执行时间(关于cron的介绍请看下面的讲解)

但是如上面代码所示打印出来的调度,可以看出来,两个调度使用的是同一个线程,这个在少量使用的过程中是没有问题的,当随着调度的增多,如果出现线程中某一个调度出错,在同一个线程中就会导致线程卡死,其他调度都不会自动调度,所以下面将介绍通过不同的线程来调用。

 

1.2、不同线程调度

在springboot框架中,已经进行了进行,因此需要新建了一个配置类如下

@Configuration
@EnableAsync
public class AsyncConfig {
    //这里标准的话使用@Value来获取配置文件中的值,这里只为测试,就直接硬编码
    private int corePoolSize = 10;
    private int maxPoolSize = 200;
    private int queueCapacity = 10;
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}

解释:

    @Configuration  提示这个类为配置工具类

    @EnableAsync  开启异步事件的支持

然后在对应的调用的方法中添加@Async注解就可以了,代码如下:

@Scheduled(fixedRate = 2000)
@Async
public void test() {
    Thread thread = Thread.currentThread();
    SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
    System.out.println("调度测试:" + "test----" +  format.format(new Date()) + "------>" + thread.getId());
}
@Scheduled(fixedRate = 2000)
@Async
public void test1() {
    Thread thread = Thread.currentThread();
    SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
    System.out.println("调度测试:" + "test1----" +  format.format(new Date()) + "----->" + thread.getId());
}

然后运行程序,打印的日志如下所示:

调度测试:test----2018-11-24 17:11:52------>53

调度测试:test1----2018-11-24 17:11:52----->54

调度测试:test----2018-11-24 17:11:54------>55

调度测试:test1----2018-11-24 17:11:54----->56

调度测试:test----2018-11-24 17:11:56------>57

调度测试:test1----2018-11-24 17:11:56----->58

调度测试:test----2018-11-24 17:11:58------>59

调度测试:test1----2018-11-24 17:11:58----->60

调度测试:test1----2018-12-24 17:12:00----->28

调度测试:test----2018-12-24 17:12:00------>29

从上面的日志可以看出来,两个调用方法对应的线程的id是不一样的,这样就可以多线程同时进行了。


2、使用Quartz

springboot整合Quartz

如果springboot是2.0.0版本以上的需要添加如下的依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-quartz</artifactId>

</dependency>

如果是1.5.9版本的添加如下的依赖:

<dependency>

<groupId>org.quartz-scheduler</groupId>

<artifactId>quartz</artifactId>

<version>2.3.0</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-context-support</artifactId>

</dependency>

创建任务类:

public class TestQuartz extends QuartzJobBean {

/**

* 执行定时任务

* @param jobExecutionContext

* @throws JobExecutionException

*/

@Override

protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {

System.out.println("quartz task "+new Date());

}

}

然后创建配置类:

@Configuration

public class QuartzConfig {

    @Bean

    public JobDetail teatQuartzDetail(){

        return JobBuilder.newJob(TestQuartz.class).withIdentity("testQuartz").storeDurably().build(); }

    @Bean

    public Trigger testQuartzTrigger(){

        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()

                .withIntervalInSeconds(10) //设置时间周期单位秒

                .repeatForever();

        return TriggerBuilder.newTrigger().forJob(teatQuartzDetail())

                .withIdentity("testQuartz")

                .withSchedule(scheduleBuilder)

                .build();

    }

}

运行测试:


 

cron的详解:

一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素

  • 秒(0~59)

  • 分钟(0~59)

  • 3 小时(0~23)

  • 4 天(0~31)

  • 5 月(0~11)

  • 6 星期(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)

  • 年份(1970-2099)

 

具体的实例如下:

 

  • 每隔5秒执行一次:/5 * ?

  • 每隔1分钟执行一次:0 /1 ?

  • 0 0 10,14,16 ? 每天上午10点,下午2点,4点

  • 0 0/30 9-17 ? 朝九晚五工作时间内每半小时

  • 0 0 12 ? * WED 表示每个星期三中午12点

  • “0 0 12 ?” 每天中午12点触发

  • “0 15 10 ? “ 每天上午10:15触发

  • “0 15 10 ?” 每天上午10:15触发

  • “0 15 10 ? *” 每天上午10:15触发

  • “0 15 10 ? 2005” 2005年的每天上午10:15触发

  • “0 14 * ?” 在每天下午2点到下午2:59期间的每1分钟触发

  • “0 0/5 14 ?” 在每天下午2点到下午2:55期间的每5分钟触发

  • “0 0/5 14,18 ?” 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

  • “0 0-5 14 ?” 在每天下午2点到下午2:05期间的每1分钟触发

  • “0 10,44 14 ? 3 WED” 每年三月的星期三的下午2:10和2:44触发

  • “0 15 10 ? * MON-FRI” 周一至周五的上午10:15触发

  • “0 15 10 15 * ?” 每月15日上午10:15触发

  • “0 15 10 L * ?” 每月最后一日的上午10:15触发

  • “0 15 10 ? * 6L” 每月的最后一个星期五上午10:15触发

  • “0 15 10 ? * 6L 2002-2005” 2002年至2005年的每月的最后一个星期五上午10:15触发

  • “0 15 10 ? * 6#3” 每月的第三个星期五上午10:15触发

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值