定时任务
2022/4/12 6:14:50
本文主要是介绍定时任务,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
定时任务的实现
-
timer
-
quartz
-
spring的scheduled
quartz
首先我们来看看quartz的使用。
使用首先要明白quartz的三个核心概念:
- Job(作业): 表示一个工作,要执行的具体内容。
- trigger(触发器): 什么时间做
- scheduler(调度器): 什么时间做什么任务
- jobDetail: 任务详细描述
基本使用
示例: 每隔5秒中提醒一次该开会了
使用步骤:
- 引入依赖
- 编写job
- 创建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 整合
- 引入 spring boot 整合quartz的依赖
- 写任务(继承 QuartzJobBean 抽象类)
- 配置 jobDetail和trigger对象
- 启动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()); }
这篇关于定时任务的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现