定时任务

发布时间:2022-06-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了定时任务脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

定时任务的实现

  • timer

  • quartz

  • sPRing的scheduled

quartz

首先我们来看看quartz的使用。

使用首先要明白quartz的三个核心概念:

  • Job(作业): 表示一个工作,要执行的具体内容。
  • trigger(触发器): 什么时间做
  • scheduler(调度器): 什么时间做什么任务
  • jobDetail: 任务详细描述

基本使用

示例: 每隔5秒中提醒一次该开会了

使用步骤:

  1. 引入依赖
  2. 编写job
  3. 创建jobDetail描述任务,创建触发器,创建调度器,通过调度器调度任务

依赖

<dePEndency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.0</version>
</dependency>

示例

package demo;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;
import java.util.Date;

public class RemindJob implements Job {

    @override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        String remindTime = new SimpleDateFormat("yy-MM-dd HH:mm:ss:SSS").format(new Date());
        System.out.println("提醒时间:" + remindTime + ", 该开会了...");
    }
}

调度器和触发器

package demo;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.concurrent.TimeUnIT;

public class SchedulerDemo {

    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 1、创建调度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        
        // 2、创建 JobDetail 实例,并与 RemindJob 类绑定(Job执行内容)
        JobDetail jobDetail = JobBuilder.newJob(RemindJob.class)
                                        .withIdentity("remindJob", "group1").build();
                                        
        // 3、构建 Trigger 实例,每隔5s执行一次
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("trigger1", "triggerGroup1")
                .startNow()//立即生效
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(5) //每隔5s执行一次
                .repeatForever()) //一直执行
                .build();

        //4、执行
        scheduler.scheduleJob(jobDetail, trigger);
        System.out.println("--------scheduler start ! ------------");
        scheduler.start();

        //睡眠
        TimeUnit.MINUTES.sleep(1);
        scheduler.shutdown();
        System.out.println("--------scheduler shutdown ! ------------");

    }
}

cron触发器

CronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用。CroTrigger是基于Cron表达式的,先了解下Cron表达式: 由7个子表达式组成字符串的,格式如下:

[秒] [分] [小时] [日] [月] [周] [年]
序号 说明 是否必填 允许填写的值 允许的通配符
1 0-59 , - * /
2 0-59 , - * /
3 0-23 , - * /
4 1-31 , - * ? / L W
5 1-12或JAN-DEC , - * /
6 1-7或SUN-SAT , - * ? / L W
7 empty 或1970-2099 , - * /
通配符表示的意思:
 * 表示每x(秒,分,天,月,日,周几)的意思
 0/5 * * * * ?  :  从0秒开始,每增加5秒执行一次
 0 0/5 * * * ?  :  从0秒开始,每增加5分钟执行一次
 5,8,12 * * * * ?:  ,表示一个列表,表示在每一分钟里面的第5秒,第8秒,第12秒各执行一次
 0 10 8,10,13 * * ?  :  在8点,10点,13点的10分的时候,各执行一次
 0 10 8-12 * * ?:  -表示多少到多少之间,在8点到12的的每小时的第10分钟的时候执行任务
 
 ?:  只能出现在表示日期或值星期几的位置
 W: workday(工作日)
 L: 最后一天,或最后一周的周几
 #: 表示第几周的意思
// 3、构建 Trigger 实例,每隔5s执行一次
Trigger trigger = TriggerBuilder
        .newTrigger()
        .withIdentity("trigger1", "triggerGroup1")
        .startNow()//立即生效
        .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
        .build();

和 spring boot 整合

  1. 引入 spring boot 整合quartz的依赖
  2. 写任务(继承 QuartzJobBean 抽象类)
  3. 配置 jobDetail和trigger对象
  4. 启动springboot项目

任务是继承 QuartzJobBean 抽象类

public class QuartzJob1 extends QuartzJobBean {

    @Override
    protected void executeinternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        String remindTime = new SimpleDateFormat("yy-MM-dd HH:mm:ss:SSS").format(new Date());
        System.out.println("提醒时间:" + remindTime + ", 该开会了...");
    }
}

创建配置类

@configuration
public class QuartzConfig {

    @Bean
    public JobDetail jobDetail1(){
        return JobBuilder.newJob(QuartzJob1.class).StoreDurably().build();
    }
     @Bean
    public Trigger trigger1(){
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(1) //每一秒执行一次
                .repeatForever(); //永久重复,一直执行下去
        return TriggerBuilder.newTrigger()
                .forJob(jobDetail1())
                .withSchedule(scheduleBuilder)
                .build();
    }
 /*   
         @Bean(name = "jobDetail")
        public MethodInvokingJobDetailFactoryBean detailFactoryBean(TimingTask task) {
            // ScheduleTask为需要执行的任务
            MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
            /*
             *  是否并发执行
             *  例如每3s执行一次任务,但是当前任务还没有执行完,就已经过了3s了.
             *  如果此处为true,则下一个任务会bing执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
             */
            jobDetail.setConcurrent(true);
            jobDetail.setName("scheduler");// 设置任务的名字
            jobDetail.setGroup("scheduler_group");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用

            /*
             * 这两行代码表示执行task对象中的scheduletest方法。定时执行的逻辑都在scheduleTest。
             */
            jobDetail.setTargetObject(task);
            jobDetail.setTargetMethod("start");
            return jobDetail;
        }
        
        @Bean
    public JobDetailFactoryBean jobDetail(){
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(HiJob.class);
        jobDetailFactoryBean.setBeanName("hiJob");
        jobDetailFactoryBean.setGroup("jobGroup");
        jobDetailFactoryBean.setDurability(true);
        return jobDetailFactoryBean;
    }

    @Bean
    public CronTriggerFactoryBean cronTrigger(JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean triggerFactoryBean = new CronTriggerFactoryBean();
        triggerFactoryBean.setCronExPression("0/5 * * * * ?");
        triggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
        return triggerFactoryBean;
    }
    */
}

spring的scheduled

在SpringBoot使用Spring Schedule非常简单,因为SpringBoot自身的starter中已经集成了Schedule,而不需要我们做更多的处理。

使用@EnableScheduling注解开启定时功能,该注解可以使用在启动类上,也可以注解于定时任务的类上。然后使用@Scheduled注解配合其参数完成定时任务。

依赖

org.springframework:spring-context 包
  • 在启动类上面使用 @EnableScheduling 开启定时任务
@SpringBootApplication
@EnableScheduling
public class SpringBootQuartzDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootQuartzDemoApplication.class, args);
    }
}

固定延时任务频率任务

  • 在要定时运行的方法上面加注解 @Scheduled
@component
public class ScheduledComponet {
    private static LOGger LOGGER = LoggerFactory.getLogger(ScheduledComponet.class) ;

    @Scheduled(fixedDelay = 5000)
    public void testSheduled() throws InterruptedException {
        TimeUnit.SECONDS.sleep(6);
        LOGGER.info("定时任务1: 线程: [ {} ],[ {} ]",Thread.currentThread().getName(),new Date());
    }

    @Scheduled(fixedRate= 3000)
    public void testSheduled2() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        LOGGER.info("定时任务2: 线程: [ {} ],[ {} ]",Thread.currentThread().getName(),new Date());
    }

    @Scheduled(cron = "0/5 * * ? * *")
    public void testSheduled3() throws InterruptedException {
        TimeUnit.SECONDS.sleep(8);
        LOGGER.info("定时任务3: 线程: [ {} ],[ {} ]",Thread.currentThread().getName(),new Date());
    }

}

注意 多个 @Scheduled 注解的方法是在一个线程中执行的,如果运行比较耗时,会阻塞其他任务的执行,使用 @Async 和 @EnableAsync 开启异步任务,可以解决,会使用异步任务线程池来运行. spring 的 cron 表达式中不允许出现字母.

@SpringBootApplication
@EnableScheduling
@EnableAsync // 开启异步
public class SpringBootQuartzDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootQuartzDemoApplication.class, args);
    }
}
    @Scheduled(fixedDelay = 5000)
    @Async // 方法异步执行
    public void testSheduled() throws InterruptedException {
        TimeUnit.SECONDS.sleep(6);
        LOGGER.info("定时任务1: 线程: [ {} ],[ {} ]",Thread.currentThread().getName(),new Date());
    }

脚本宝典总结

以上是脚本宝典为你收集整理的定时任务全部内容,希望文章能够帮你解决定时任务所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。