定时任务

696 阅读3分钟

近日项目开发中需要在每天日定时分析一次前一天的日志信息,借此机会整理了一下在spring环境下几种定时任务的实现方式:

分类

  • java.util.Timer
    用于管理在后台执行的延迟任务或周期性任务,可以按照固定频率或固定延迟时间执行。
  • Quartz
    一个轻量级的Java库,几乎可以集成到任何应用系统中的框架。
  • task
    spring3.0自带的Timer,使用更加简便。

用法

  • java自带Timer实现

    以下案例schedule()方法内的第一个参数为TimerTask task,为需要执行的任务,第二个参数为long delay为延时启动时间,第三个参数long period为执行周期。程序效果为2s后开始执行,5s执行一次。

    new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println("Timer is running");
                }
            }, 2000,5000);
    

    由于自带Timer有以下缺陷,所以使用场景较少:

  • 可以让程序以某个频率执行,但无法实现在指定时间运行;
  • 执行任务的线程只有一个,当某一任务执行时间过长影响其他定时任务的准确性;
  • 没有持久化机制;
  • Timers没有真正的管理计划;
  • Quartz实现

    • 第一步:定义job基类

      • 方式1——不继承基类

      @Component
      public class MyJob1 {
          public void sayHello() {
              System.out.println("hello MyJob1...");
          }
      }
      public class MyWork {
          public void sayHello() {
              System.out.println("hello MyWork....");
          }
      }
      
    • 方式2——继承QuartzJobBean

      public class Myjob2 extends QuartzJobBean {
      
          HelloService helloService;
      
          public HelloService getHelloService() {
              return helloService;
          }
      
          public void setHelloService(HelloService helloService) {
              this.helloService = helloService;
          }
      
          @Override
          protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
              helloService.helloSe();
          }
      }
      
      
    • 第2步:提供JobDetail和配置作业类的触发器

      JobDetail也有两种提供方式

      • 方式1————使用 MethodInvokingJobDetailFactoryBean

      @Configuration
      public class QuartzConfig {
          @Bean
      JobDetail methodInvokingJobDetailFactoryBean() {
              MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
              bean.setTargetBeanName("myJob1");//设置目标Bean(就是Job Bean的名字)
              bean.setTargetMethod("sayHello");//设置目标方法名
              return bean;
          }
      }
      
      • 方式2————使用 JobDetailFactoryBean

      @Configuration
      public class QuartzConfig {
          @Bean
          JobDetail jobDetailFactoryBean() {
              JobDetailFactoryBean bean = new JobDetailFactoryBean();
              bean.setJobClass(MyJob2.class);
              JobDataMap map = new JobDataMap();
              map.put("myWork", new MyWork());
              bean.setJobDataMap(map);
              return bean;
          }
      }
      

      触发器配置

      Quartz的作业触发器有两种,分别是 org.springframework.scheduling.quartz.SimpleTriggerBean org.springframework.scheduling.quartz.CronTriggerBean
      • 方式1————使用 SimpleTriggerFactoryBean

      @Bean
          SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
              SimpleTriggerFactoryBean bean = new SimpleTriggerFactoryBean();
              bean.setStartTime(new Date());
              bean.setRepeatCount(3);
              bean.setRepeatInterval(2000);
              bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());
              return bean;
          }
      
      • 方式2————使用 CronTrigger

      @Bean
          CronTrigger cronTriggerFactoryBean() {
              CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
              bean.setCronExpression("0/5 * * * * ?");
              bean.setJobDetail(jobDetailFactoryBean().getObject());
              return bean;
          }
      

      配置SchedulerFactoryBean

      @Bean
          SchedulerFactoryBean schedulerFactoryBean() {
              SchedulerFactoryBean bean = new SchedulerFactoryBean();
                                                                                      
              bean.setTriggers(simpleTriggerFactoryBean().getObject(),cronTriggerFactoryBean().getObject());
              return bean;
          }
      
    • 第3步:开启测试

      @SpringBootApplication
      @EnableScheduling
      public class Application {
          public static void main(String[] args) {
              SpringApplication.run(Application.class, args);
          }
      }
      
  • task——Spring3.0

    • 第一步:定义基类

    即普通的pojo
    @Service
    public class HelloService {
        public String helloSe() {
    
            return "hello service";
        }
    }
    
  • 第2步:开启定时任务

    @Component
    public class Myschedule {
    
        @Scheduled(fixedDelay = 2000)
        public void sch1() {
            System.out.println("fixedDelay执行"+new Date());
        }
    
        @Scheduled(fixedRate = 2000)
        public void sch2() {
            System.out.println("fixedRate执行"+new Date());
        }
    
        @Scheduled(initialDelay = 2000,fixedDelay = 2000)
        public void sch3() {
            System.out.println("initialDelay"+new Date());
        }
    
        @Scheduled(cron ="" )
        public void sch4() {
            System.out.println("initialDelay"+new  Date());
        }
    
    }
    

参数解释

  • cron:指定cron表达式
  • fixedDelay:An interval-based trigger where the interval is measured from the completion time of the previous task. The time unit value is measured in milliseconds.即表示从上一个任务完成开始到下一个任务开始的间隔,单位是毫秒。
  • fixedRate:An interval-based trigger where the interval is measured from the start time of the previous task. The time unit value is measured in milliseconds.即从上一个任务开始到下一个任务开始的间隔,单位是毫秒。