开发应该知道的定时任务

您所在的位置:网站首页 查看定时任务是否执行 开发应该知道的定时任务

开发应该知道的定时任务

2023-10-06 09:03| 来源: 网络整理| 查看: 265

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9天,点击查看活动详情”

1.简介

在日常的开发工作中我们经常会遇到定时任务的相关问题,比如:

信用卡定时每月给用户推送账单数据; 轮训更新某个任务的状态是否完成; 设置一个定时提醒; 邮件或消息设置定时发送; 定时统计某个时间段的数据存入缓存;

等等,定时可以算一个最常用的开发工作,你日常的工作中肯定也写了不少的定时任务代码,但是你真的了解定时任务吗?

下面让我们一起进入定时任务的学习!

2.基础 2.1 Cron表达式

cron是当前做定时任务的基础,即使很多人说cron表达式不容易理解,但这是现在阶段所有程序编写定时任务的基础和唯一选择。就算做不到熟练编写,也应该做到看到能懂;

Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义;

例如:

每隔5秒执行一次:*/5 * * * * ? 每隔1分钟执行一次:0 */1 * * * ? 每天23点执行一次:0 0 23 * * ? 每天凌晨1点执行一次:0 0 1 * * ? 每月1号凌晨1点执行一次:0 0 1 1 * ? 每月最后一天23点执行一次:0 0 23 L * ? 每周星期天凌晨1点实行一次:0 0 1 ? * L 在26分、29分、33分执行一次:0 26,29,33 * * * ? 每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ? 2.2 定时任务的三大组成部分

调度器Scheduler、执行器 executors、触发器 Trigger

不管你使用的什么框架、用的是什么系统,或者将来又出现什么新的定时任务技术,都离不开这三部分。

我们以一个闹钟响铃的任务为例:

执行器executors:发出一阵刺耳的声音;(具体的执行操作)

触发器Trigger:发出声音的具体时间; (触发任务执行的规则,多为时间规则。)

调度器Scheduler:一直运行到触发时间点发出刺耳的声音;(进行任务的调度)

所以,当接手一个新的定时任务的框架,首先要看其这三部分是这么去实现的;

3.Java定时任务 3.1 JDK seelp实现定时任务

使用Thread.sleep()方法实现定时任务。可以在独立的线程中执行任务,并在每次任务完成后使用Thread.sleep()方法让线程休眠一段时间。

下面是一个示例,该示例定义了一个任务,该任务每隔1秒打印“hello timer”:

public class TimerExample { public static void main(String[] args) { Runnable task = new Runnable() { public void run() { while (true) { System.out.println("hello timer"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread thread = new Thread(task); thread.start(); } }

请注意,在本例中,任务是在无限循环中执行的,并且每次任务完成后线程都会休眠1秒。如果想要执行特定次数的定时任务,可以在任务内部使用计数器并在达到特定次数后终止循环。

3.2 JDK Timer & TimerTask 实现定时任务

使用Java的java.util.Timer和java.util.TimerTask类来创建定时任务。

下面是一个简单的例子,其中定义了一个任务,该任务每隔1秒执行一次:

import java.util.Timer; import java.util.TimerTask; public class TimerExample { public static void main(String[] args) { TimerTask task = new TimerTask() { public void run() { System.out.println("Task executed"); } }; Timer timer = new Timer(); long delay = 1000; long interval = 1000; timer.scheduleAtFixedRate(task, delay, interval); } }

在上面的代码中,创建了一个TimerTask对象,该对象的run方法定义了要执行的任务。然后,使用Timer类创建了一个定时器,并使用scheduleAtFixedRate方法指定了任务的执行频率(即每隔1秒执行一次)。

请注意,java.util.Timer是非线程安全的,因此在多线程环境中使用时需要注意。如果需要更复杂的定时任务,请考虑使用其他库,例如java.util.concurrent中的ScheduledExecutorService。

3.3 JDK ScheduledExecutorService

ScheduledExecutorService是Java中另一个用于创建定时任务的类。可以使用它创建和执行定期执行的任务,并且可以控制任务的执行频率。

以下是一个示例,该示例每隔1秒钟打印“hello timer”:

import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledExecutorServiceExample { public static void main(String[] args) { ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); Runnable task = new Runnable() { public void run() { System.out.println("hello timer"); } }; executor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); } }

在本例中,使用Executors类的newScheduledThreadPool方法创建了一个ScheduledExecutorService对象,并使用该对象的scheduleAtFixedRate方法将任务安排在每隔1秒钟执行一次。可以根据需要更改任务的执行频率。

3.4 Spring Task中的 @schedule

在Java中,可以使用@Scheduled注解实现定时任务。该注解可以在Spring项目中使用,以在指定的时间间隔内自动调用指定方法。

以下是一个示例,该示例每隔1秒钟打印“hello timer”:

import org.springframework.scheduling.annotation.Scheduled; public class ScheduledAnnotationExample { @Scheduled(fixedRate = 1000) public void printMessage() { System.out.println("hello timer"); } }

在本例中,使用@Scheduled注解将任务标记为定时任务,并使用fixedRate属性设置任务的执行频率,即每隔1秒钟执行一次。

3.5 Quartz框架

Quartz是一个强大的任务调度框架,可用于在Java应用程序中创建定时任务。可以使用Quartz创建简单的周期性任务,也可以创建复杂的作业调度,例如每周一次的作业。

以下是一个使用Quartz创建定时任务的示例:

import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; public class QuartzExample { public static void main(String[] args) throws SchedulerException { JobDetail job = JobBuilder.newJob(HelloJob.class) .withIdentity("myJob", "group1") .build(); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger", "group1") .startNow() .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(1) .repeatForever()) .build(); Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); scheduler.scheduleJob(job, trigger); } } public class HelloJob implements Job { public void execute(JobExecutionContext context) { System.out.println("hello timer"); } }

在本例中,创建了一个名为HelloJob的作业类,该类实现了Quartz的Job接口。还创建了一个作业详细信息对象和一个触发器对象,并使用触发器安排了每隔1秒钟执行一次的任务。最后,启动了调度程序并使用其scheduleJob方法将任务与触发器关联。

3.6 Elastic-Job框架

Elastic-Job是一个分布式作业调度框架,提供了高可用性、高扩展性等功能,可以用于创建分布式定时任务。

以下是使用Elastic-Job创建一个简单的定时任务的示例:

import com.dangdang.ddframe.job.api.ShardingContext; import com.dangdang.ddframe.job.api.simple.SimpleJob; public class MyJob implements SimpleJob { @Override public void execute(ShardingContext shardingContext) { System.out.println("Hello, world!"); } }

在本例中,创建了一个名为MyJob的作业类,该类实现了Elastic-Job的SimpleJob接口。可以在execute方法中编写定时执行的代码。还需要创建一个作业配置文件,该文件配置了任务的定时时间和任务的执行策略。

3.7 XXL-JOB框架

XXL-JOB是一个Java分布式定时任务解决方案,提供了高可用性、高扩展性等功能,可以用于创建分布式定时任务。

以下是使用XXL-JOB创建一个简单的定时任务的示例:

import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.handler.annotation.JobHandler; import com.xxl.job.core.log.XxlJobLogger; import org.springframework.stereotype.Component; @JobHandler(value="myJobHandler") @Component public class MyJobHandler extends IJobHandler { @Override public ReturnT execute(String param) throws Exception { XxlJobLogger.log("Hello, world!"); return SUCCESS; } }

在本例中,创建了一个名为MyJobHandler的作业类,该类继承了XXL-JOB的IJobHandler类。可以在execute方法中编写定时执行的代码。还需要通过注解@JobHandler声明作业处理器名称,并在作业配置中将作业处理器与作业关联。

3.8 PowerJob框架

PowerJob是一种使用Java语言编写的分布式任务调度系统,可以用于创建定时任务。

以下是使用PowerJob创建一个简单的定时任务的示例:

import com.dangdang.ddframe.job.api.ShardingContext; import com.dangdang.ddframe.job.api.simple.SimpleJob; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MyJob implements SimpleJob { private static final Logger logger = LoggerFactory.getLogger(MyJob.class); @Override public void execute(ShardingContext shardingContext) { logger.info("Hello, world!"); } }

在本例中,创建了一个名为MyJob的简单作业类,该类实现了PowerJob的SimpleJob接口。可以在execute方法中编写定时执行的代码。

4. 总结

本文只是简单的对Java项目中的定时任务做了一些介绍,告诉大家有哪些方式实现定时任务,并给出了最简单的demo,后面如果有时间也准备把每种定时任务的优劣势进行分析,新框架为何替代旧框架。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3