小鸡炸

导航

SpringBoot_SpringTask_Quartz

一、SpringTask和Quartz

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

二、SpringTask的使用

1、导入jar包:spring-context.jar包就带这个功能、所以选择 web就可以使用了
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
2、编写一个类,被Spring管理即可执行
import java.util.Date;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

@Component
public class TaskTools {
	static int count=0;
	
	@Scheduled( fixedRate = 5000 )
    public void test001() {
        System.out.println("无论上一次执行需要多少秒,我都会在5秒后执行:"+new Date().getSeconds());
        try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    }
	
	@Scheduled( fixedDelay = 5000 )
    public void test002() {
        System.out.println("上一次执行完毕后,再过5秒,我再执行:"+new Date().getSeconds());
        try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    }
	
	//@Scheduled(cron = "0 0/1 * * * ? ")
    public void test003(){
        System.out.println("我会每隔1分钟执行一次");
	}
	
	//initialDelay 初始化延迟时间,也就是标识第一次延迟执行的时间,只能配合 fixedDelay 或 fixedRate 使用
	//@Scheduled(initialDelay = 5000, fixedRate = 5000)
    public void test004() {
        System.out.println("第一次执行需要5秒后");
    }
}
3、@Scheduled常用属性介绍
属性名 属性作用
fixedRate 上一次执行无论需要多少秒结束,我都会在5秒后执行
fixedDelay 上一次执行完毕后,我再执行
cron Cron表达式:在线生成https://cron.qqe2.com/
initialDelay 初始化延迟时间,也就是标识第一次延迟执行的时间,只能配合 fixedDelay 或 fixedRate 使用
4、启动类添加注解
@SpringBootApplication
@EnableScheduling
public class Springboot004Application {

	public static void main(String[] args) {
		SpringApplication.run(Springboot004Application.class, args);
	}
}
5、CronExpression表达式详解

https://www.jianshu.com/p/1defb0f22ed1

在线制作Cron表达式:https://www.bejson.com/othertools/cron/

格式为:{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}

cron表达式各占位符解释:

以下为{秒数}的案例 ==> 允许值范围: 0~59 ,不允许为空值,若值不合法,调度器将抛出SchedulerException异常

"*" 代表每隔1秒钟触发;

"," 代表在指定的秒数触发,比如"0,15,45"代表0秒、15秒和45秒时触发任务

"-" 代表在指定的范围内触发,比如"25-45"代表从25秒开始触发到45秒结束触发,每隔1秒触发1次

"/" 代表触发步进(step),"/"前面的值代表初始值(""等同"0"),后面的值代表偏移量,比如"0/20"或者"/20"代表从0秒钟开始,每隔20秒钟触发1次,即0秒触发1次,20秒触发1次,40秒触发1次;"5/20"代表5秒触发1次,25秒触发1次,45秒触发1次;"10-45/20"代表在[10,45]内步进20秒命中的时间点触发,即10秒触发1次,30秒触发1次

三、Quartz的使用

1、导入jar包

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-quartz</artifactId>
		</dependency>

2、创建一个【被调度的类】

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

public class MyJob implements Job {
    private void before() {
        System.out.println("任务开始执行");
    }
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        before();
        System.out.println("开始:" + System.currentTimeMillis());
        JobDataMap jdMap = context.getJobDetail().getJobDataMap();  //获得传递过来的参数
        System.out.println(jdMap.get("key"));
        System.out.println("结束:" + System.currentTimeMillis());
        after();
    }

    private void after() {
        System.out.println("任务开始执行");
    }
}

3、创建一个调用【任务调度服务】

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/student")
public class MyController {
	@Autowired
	Scheduler scheduler;

	@RequestMapping(value = "/index001")
	public void testTask() throws SchedulerException {
		JobDetail jobDetail = JobBuilder.newJob(MyJob.class).withIdentity("job2", "group2").build();
		jobDetail.getJobDataMap().put("key", "张三"); // 给自定义任务传值
		CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/1 * * * ?");
		CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2")
				.withSchedule(cronScheduleBuilder).build();

		scheduler.scheduleJob(jobDetail, cronTrigger);
	}

	Trigger trigger = TriggerBuilder.newTrigger().withIdentity("Trigger_HelloQuartz", "group1") // 定义name/group
			// .startNow()//一旦加入scheduler,立即执行11
			.startAt(new Date(System.currentTimeMillis() + 5000))// 5秒后执行
			.withSchedule(SimpleScheduleBuilder.simpleSchedule() // 使用SimpleTrigger
					.withIntervalInSeconds(2) // 每隔2秒执行一次
					.withRepeatCount(1))// 重复1次,共计2次
			// .repeatForever()) //一直执行,奔腾到老不停歇
			.build();
}

posted on 2022-01-19 10:46  小鸡炸  阅读(100)  评论(0编辑  收藏  举报