Java定时任务

Java自带的API

java.util.Time类, java.util.TimerTask类

Quartz框架

开源,功能强大,使用起来稍显复杂

public static void main(String[] args) {
      try {
          //调度器
          Scheduler defaultScheduler = StdSchedulerFactory.getDefaultScheduler();
          defaultScheduler.start();

//           defaultScheduler.pauseTriggers(triggerKeyGroupMatcher);
          //任务详情 一个任务可以被多个触发器调度
          JobDetail job = newJob(HelloJob.class)
                  .withIdentity("job1", "group1")//任务名称,任务组名称
                  .build();

          JobDetail job2 = newJob(HelloJob.class)
                  .withIdentity("job2", "group1")//任务名称,任务组名称
                  .build();


          //触发器 一个触发器只能调度一个任务
          Trigger trigger = newTrigger()
                  .withIdentity("trigger1", "group1")//调度器名称,调度器组名称
                  .startNow()//马上启动
                  .withSchedule(
                          SimpleScheduleBuilder.simpleSchedule()
                              .withIntervalInSeconds(1)//每隔5秒出发一次
                              .repeatForever())//一直执行
                  .build();

          //触发器1
          Trigger trigger2 = newTrigger()
                  .withIdentity("trigger2", "group1")//调度器名称,调度器组名称
                  .startNow()//马上启动
                  .forJob("job2", "group1")//指定任务
                  .withSchedule(
                          SimpleScheduleBuilder.simpleSchedule()
                              .withIntervalInSeconds(3)//每隔5秒出发一次
                              .withRepeatCount(1)) //指定执行次数,只执行一次
                  .build();


          //把触发器和任务交给调度器,调度器会按照触发器配置的规则去触发任务
          defaultScheduler.scheduleJob(job, trigger);
          defaultScheduler.scheduleJob(job2, trigger2);
          TimeUnit.SECONDS.sleep(3);

          defaultScheduler.shutdown();
      } catch (SchedulerException e) {
          e.printStackTrace();
      } catch (InterruptedException e) {
          e.printStackTrace();
      }

  }
public static void main(String[] args) {
      try {
          //调度器
          Scheduler defaultScheduler = StdSchedulerFactory.getDefaultScheduler();
          defaultScheduler.start();

//           defaultScheduler.pauseTriggers(triggerKeyGroupMatcher);
          //任务详情 一个任务可以被多个触发器调度
          JobDetail job = newJob(HelloJob.class)
                  .withIdentity("job1", "group1")//任务名称,任务组名称
                  .build();



          //触发器 一个触发器只能调度一个任务
          Trigger trigger = newTrigger()
                  .withIdentity("trigger1", "group1")//调度器名称,调度器组名称
                  .startNow()//马上启动
                  .withSchedule(
                          /***
                            *
                            *
                            * @auther wangxiang
                            * @date 2022/8/9 13:45
                            * 秒 分 时 日 月 星期 年
                            * 0-5表示 0到5秒每秒都执行
                            * 0,5表示 0和5秒各执行一次
                            * 0/5表示 每5秒执行一次
                            *
                            *
                            * ?表示不知道
                            * L表示最后一天(日和周)
                            * W表示工作日
                            * 年是可选的
                            */
                          //*/5表示 每5秒执行一次


                          CronScheduleBuilder.cronSchedule("* * * * * ? *")
                  )
                  .build();


          //获取当前时间30天后的时间
          LocalDateTime localDateTime = LocalDateTime.now().plus(30,ChronoUnit.DAYS);

          //把触发器和任务交给调度器,调度器会按照触发器配置的规则去触发任务
          defaultScheduler.scheduleJob(job, trigger);
          TimeUnit.SECONDS.sleep(3);

          defaultScheduler.shutdown();
      } catch (SchedulerException e) {
          e.printStackTrace();
      } catch (InterruptedException e) {
          e.printStackTrace();
      }

  }

 

 

Spring Task

spring3.0以后自带task调度工具,比Quartz更加的简单方便

实现方式:

纯XML配置方式

image-20220909093146092

  • 简单的定时任务

    实现业务功能+配置定时规则

    initial-delay:设置服务器启动完毕后等多少毫秒后开始执行定时任务

    fixed-delay:每隔多少毫秒执行一次

  • 复杂定时任务

    cron表达式

    image-20220909092736142

     

    image-20220909092705143

     

     

     

全注解方式

image-20220909093352656

image-20220909093439347

image-20220909093515850

  • 在业务方法上提供注解

  • 开启注解支持

 

spring boot 实现定时任务

@Component
public class MyTask {

   @Scheduled(initialDelay = 1000,fixedDelay = 1000)
   public void myTask1(){
       System.out.println("第一个定时任务");
  }

   @Scheduled(initialDelay = 2000,fixedDelay = 3000)
   public void myTask2(){
       System.out.println("第二个定时任务");
  }


   @Scheduled(cron = "*/5 * * * * ?")
   public void myTask3(){
       System.out.println("第三个定时任务");
  }

   @Scheduled(cron = "* */1 * * * ?")
   public void myTask4(){
       System.out.println("第四个定时任务");
  }
}
@SpringBootApplication
@EnableScheduling
@ComponentScan
public class SpringTaskDempApplication {

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

 

 

总结

Quartz 默认多线程异步执行 单个任务时,在上一个调度未完成时,下一个调度时间到时,会另起一个线程开始新的调度。业务繁忙时,一个任务会有多个调度,可能导致数据处理异常。 多个任务时,任务之间没有直接影响,多任务执行的快慢取决于CPU的性能 触发方式 : (1)SimpleTrigger (2)CronTrigger 需要在配置文件中实现配置Job 能被集群实例化,支持分布式部署 使用JobStoreCMT(JDBCJobStore的子类),Quartz 能参与JTA事务;Quartz 能管理JTA事务(开始和提交)在执行任务之间,这样,任务做的事就可以发生在JTA事务里。 Task 默认单线程同步执行 单个任务时,当前次的调度完成后,再执行下一次任务调度 多个任务时,一个任务执行完成后才会执行下一个任务。若需要任务能够并发执行,需手动设置线程池 触发方式: 与Quartz的CronTrigger的表达式类似 可以使用注解标注定时任务 比较: 实现,Task注解实现方式,比较简单。Quartz需要手动配置Jobs。 任务执行,Task默认单线程串行执行任务,多任务时若某个任务执行时间过长,后续任务会无法及时执行。Quartz采用多线程,无这个问题。 调度,Task采用顺序执行,若当前调度占用时间过长,下一个调度无法及时执行; Quartz采用异步,下一个调度时间到达时,会另一个线程执行调度,不会发生阻塞问题,但调度过多时可能导致数据处理异常 部署,Quartz可以采用集群方式,分布式部署到多台机器,分配执行定时任务

posted on 2022-11-22 11:11  太阳当空照```  阅读(155)  评论(0)    收藏  举报

导航