【Java 定时任务】crontab定时任务配置(139)

news2025/2/26 5:33:09

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

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

一、基础

什么是Crontab?
Crontab,即Cron Table(时间表)的简称,是一个在Linux和Unix系统中用于管理定时任务的调度器。它可以帮助我们在指定的时间周期性地执行某些任务,如定期备份数据、发送邮件提醒等。想象一下,Crontab就像一位贴心的秘书,在你需要的时间准时执行你交代的任务。

Crontab的工作原理
Crontab的工作原理非常简单,它由一个名为“Cron”的守护进程来负责定时执行任务。当你创建了一个Crontab任务时,Cron守护进程会按照你设定的时间规则来周期性地执行这个任务。这个过程就像是你将一首歌设置为闹钟铃声,每天早上都会按时响起,叫醒你。

1.1 Cron表达式

cron是当前做定时任务的基础,即使很多人说cron表达式不容易理解,但这是现在阶段所有程序编写定时任务的基础和唯一选择。

就算做不到熟练编写,也应该做到看到能懂;

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

接下来具体看cron属性对应时间表达式的定义规则:

按顺序依次是:秒、分、时、日、月、周,中间用空格间隔
月、周可以用数字或英文单词的前三个字母表示
日和周可能会冲突,因此两个可以有一个配置为?
常用通配符的含义:
表示任意值,例如在秒字段上设置,表示每秒都触发
?表示不指定值,只能出现在日或者周的位置,用于处理日和周可能存在的冲突,例如2020年8月15是周六,如果又在周的位置上指定为周一,那就会产生冲突到导致定时任务失效。如果我们不关心日或者周的时候,也可以将其设置为?
-表示时间区间,例如在秒上设置1-3,表示第1、2、3秒都会触发
/表示时间间隔,例如在秒上设置2/4,表示从第2秒开始每间隔4秒触发一次
,表示列举多个值,例如MON,WED,FRI表示周一、周三、周五触发
例如:

每隔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 * * ?

1.2 定时任务的三大组成部分
调度器Scheduler、执行器 executors、触发器 Trigger

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

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

执行器executors:发出一阵刺耳的声音;(具体的执行操作)
触发器Trigger:发出声音的具体时间; (触发任务执行的规则,多为时间规则。)
调度器Scheduler:一直运行到触发时间点发出刺耳的声音;(进行任务的调度)

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

二、Java做定时任务的技术方案比较

Java做定时任务的技术方案有多种,本文将比较常见的技术方案,分析它们的优缺点,以便开发人员在实际项目中选择合适的技术方案。

2.1、JDK seelp实现定时任务
使用Thread.sleep()方法实现定时任务。可以在独立的线程中执行任务,并在每次任务完成后使用Thread.sleep()方法让线程休眠一段时间。
下面是一个示例,该示例定义了一个任务,该任务每隔1秒打印“执行任务每秒一次”:

public class TimerExample {
    public static void main(String[] args) { 
        Runnable task = new Runnable() { 
            public void run() { 
                while (true) { 
                    System.out.println("执行任务每秒一次"); 
                    try { 
                        Thread.sleep(1000); 
                    } catch (InterruptedException e) { 
                        e.printStackTrace(); 
                    } 
                } 
           } 
      }; 
      Thread thread = new Thread(task); 
      thread.start(); 
      } 
}

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

2.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("执行任务每秒一次"); 
            } }; 
            
            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。

在Java 5之前,它是唯一的定时任务工具,在Java 5之后,JDK提供了更好的替代方案。

优点:
轻量级,使用简单。
可以实现较为简单的定时任务功能。
缺点:
不支持复杂的定时任务类型,如cron表达式
不支持任务持久化
在定时任务数量很多的情况下,性能可能存在问题
不支持分布式

2.3、JDK ScheduledExecutorService
ScheduledExecutorService是Java 5新增的一个接口,它位于java.util.concurrent包内,可以通过ThreadPoolExecutor来实现。可以使用它创建和执行定期执行的任务,并且可以控制任务的执行频率。
它可以很方便地实现定时任务,支持多种执行方式,比如单次定时、固定频率定时和固定延迟时间定时等。
以下是一个示例,该示例每隔1秒钟打印“执行任务每秒一次”:

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("执行任务每秒一次");
            } 
        }; 
        executor.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); 
     } 
}

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

优点:
简单易用,可灵活配置。
支持多种定时任务类型,灵活度高。
支持并发调度,可以提高性能。
缺点:
不支持分布式
任务执行结果管理不够方便

2.4、Quartz框架
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("执行任务每秒一次");
    } 
}

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

优点:
功能丰富,支持多种定时任务类型。
支持任务持久化,保证任务不会丢失。
支持分布式,可以实现任务的高可用和负载均衡。
缺点:
依赖比较大,使用起来比较复杂。
配置较为繁琐,需要考虑集群和持久化等问题。

2.5、Spring Task 中的 @schedule
Spring Task是Spring框架提供的一个模块,可以用来进行定时任务的管理。通过@Scheduled注解,可以实现简单的定时任务设置。同时也支持通过cron表达式设置复杂的定时任务。
以下是一个示例,该示例每隔1秒钟打印“执行任务每秒一次”:

import org.springframework.scheduling.annotation.Scheduled; 

public class ScheduledAnnotationExample { 
    @Scheduled(fixedRate = 1000) 
    public void printMessage() { 
        System.out.println("执行任务每秒一次"); 
    } 
}

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

优点:
集成简单,开发便捷。
支持使用注解来配置定时任务,使得代码更加易读易维护。
缺点:
不支持分布式
不支持任务持久化

2.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("执行任务每秒一次"); 
	} 
}

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

2.7、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("执行任务每秒一次"); 
    } 
}

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

2.8、Xxl-job
Xxl-job是一个Java分布式定时任务解决方案,提供了高可用性、高扩展性等功能,可以用于创建分布式定时任务。可以用来代替Quartz。它支持类似cron表达式的定时任务设置,支持多种执行器类型,比如本地任务、Shell任务、Http任务等。同时还支持任务执行结果的管理和调度中心的高可用等特性。
以下是使用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<String> execute(String param) throws Exception { 
        XxlJobLogger.log("执行任务每秒一次"); 
        return SUCCESS; 
    } 
}

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

优点:
操作简单,集成容易。
多种任务执行器类型,支持更多的任务类型。
支持可视化的调度中心,调度管理更加方便。
缺点:
比较适合定时任务数量较多,任务类型较为丰富的情况,对于简单的定时任务使用稍显繁琐。

三、共同点和不同点
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1087671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高压放大器在软体机器人领域的应用

软体机器人是一种新型机器人技术&#xff0c;与传统的硬体机器人有着很大的不同。软体机器人通常由柔软的材料制成&#xff0c;具有高度的柔韧性和灵活性&#xff0c;并且可以实现多种形状和动作。但是&#xff0c;软体机器人的发展面临很多技术挑战&#xff0c;其中之一就是控…

信息与网络安全基础知识汇总

需要面试真题和考证资料的 面试真题考证资料点我领取 面试真题考证资料点我领取 面试真题考证资料点我领取 一、概述 1.网络信息安全基本概念 信息安全&#xff1a;是指信息网络中的硬件、软件及其系统中的数据受到保护&#xff0c;不受偶然的或者恶意的原因而遭到破…

2023年中国潜望式镜头市场发展趋势分析:潜望式镜头渗透将进一步提升[图]

随着摄像技术的渐渐成熟&#xff0c;专业摄影师对镜头的要求越来越高&#xff0c;所以产生了潜望式镜头&#xff0c;“潜望镜式变焦”镜头俗称“内变焦”镜头&#xff0c;由于光学变焦是在机身内部完成&#xff0c;所以可以很容易安装滤镜&#xff0c;无需额外安装镜头筒。其次…

推荐16款最好的3dMax插件

3DMAX本身就是一个非常复杂的3d软件,有许多功能。所有的建模、动画和模拟工具都在其中.然而,也有由外部作者创建的插件或脚本。 这些插件可以显著改善和促进3DMAX的工作的。在许多情况下,它们超出了这个应用程序的基本工具,并引入了原始创造者未提供的功能。下面就给大家介绍…

C语言之文件操作篇(1)

目录 为什么要使用文件 什么是文件 文件名 文件名的访问路径 相对路径 绝对路径 文件类型 文件缓冲区 文件指针 文件的打开与关闭 fopen fclose 打开方式如下 w r 今天我们来介绍C语言的文件操作。之前我们实现的通讯录有两个问题 信息太多&#xff0c;空间小了…

什么是无人直播呢?

无人直播是指通过技术手段实现直播间不停播&#xff0c;从而无需主播真人出镜参与直播。这种直播方式通常需要使用一些特定的软件或工具&#xff0c;例如虚拟背景软件等。 无人直播通常用于一些商业目的&#xff0c;如广告宣传、产品销售等。 通过无人直播&#xff0c;商家可…

2023年中国在线问诊行业发展历程及趋势分析:线上医疗将朝服务多样化、智慧化发展[图]

在线问诊是指通过开设线上义诊等通道进行诊疗的活动&#xff0c;主要作用是可防止线下就诊造成交叉感染。在线问诊平衡医疗资源供给&#xff0c;但问诊顺利开展的前提是可以提供专业的诊断或医疗建议。线上问诊病人很难甄别医生的资质&#xff0c;所以只能作基础性诊断参考。 …

ssm+vue的培训学校教学管理平台(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的培训学校教学管理平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结…

keepalived+nginx实现高可用

1.安装keepalived、nginx yum install keepalived –y//centos默认无nginx源 rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpmyum install -y nginx2.修改keepalived配置文件&#xff08;/etc/keepalived/keepalived.c…

代码随想录算法训练营第六十二、六十三天 | 单调栈 part 2 | 503.下一个更大元素II 、42. 接雨水、84.柱状图中最大的矩形

目录 503.下一个更大元素II思路代码 42. 接雨水思路一 双指针思路二 单调栈代码 84.柱状图中最大的矩形思路一 双指针思路二 单调栈代码 503.下一个更大元素II Leetcode 思路 将数组乘2来遍历即可&#xff0c;就是加长版的每日温度。 但是处理起来会有细节&#xff0c;如果…

Annoy vs Milvus:哪个向量数据库更适合您的AI应用?知其然知其所以然

1. Annoy vs Milvus简介 Annoy 和 Milvus 都是用于向量索引和相似度搜索的开源库&#xff0c;它们可以高效地处理大规模的向量数据。 Annoy&#xff08;Approximate Nearest Neighbors Oh Yeah&#xff09;&#xff1a; Annoy 是一种近似最近邻搜索算法&#xff0c;它通过构…

微信小程序服务通知(订阅消息)定时推送消息功能

首先先说项目需求&#xff1a;向预约参观的用户提前一天晚上8点推送消息。小程序端主要用到的API是我是小程序用到的API。以及服务端用到的API&#xff1a;我是服务端用到的API。 1. 开通订阅消息功能 (1)、 首先需要在小程序管理后台开通订阅消息功能。没开通前如下图所示: …

解读提示工程(Prompt Engineering)

提示工程&#xff08;Prompt Engineering&#xff09;&#xff0c;也称为上下文提示&#xff0c;是一种通过不更新模型的权重/参数来引导LLM行为朝着特定结果的方法。这是与AI有效交流所需结果的过程。提示工程可以用于各种任务&#xff0c;从回答问题到算术推理乃至各种应用领…

Python爬虫技术

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

只有正规才有机会,CTF/AWD竞赛标准参考书来了

目录 前言 一、内容简介 二、读者对象 三、目录 前言 随着网络安全问题日益凸显&#xff0c;国家对网络安全人才的需求持续增长&#xff0c;其中&#xff0c;网络安全竞赛在国家以及企业的人才培养和选拔中扮演着至关重要的角色。 在数字化时代&#xff0c;企业为了应对日益…

Lua在计算时出现非法值,开启Debugger之后不再触发

1&#xff09;Lua在计算时出现非法值&#xff0c;开启Debugger之后不再触发 2&#xff09;从Gamma空间改为Linear空间会导致性能下降吗 3&#xff09;EXR格式在Unity中如何优化 4&#xff09;安卓游戏启动后提示“应用程序异常” 这是第355篇UWA技术知识分享的推送&#xff0c;…

事务管理 AOP

一、Spring事务管理 1.Transactional//Spring 事务管理 2.事务进阶 1.事务属性-回滚&#xff08;rollbackFor&#xff09; 2.传播属性&#xff08;propagation&#xff09; 1.DeptLog日志对象 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsC…

完整教程:Java+Vue+Websocket实现OSS文件上传进度条功能

引言 文件上传是Web应用开发中常见的需求之一&#xff0c;而实时显示文件上传的进度条可以提升用户体验。本教程将介绍如何使用Java后端和Vue前端实现文件上传进度条功能&#xff0c;借助阿里云的OSS服务进行文件上传。 技术栈 后端&#xff1a;Java、Spring Boot 、WebSock…

开源在线客服系统源码微信小程序

又来啦&#xff01;今天要给大家分享的是一款在线客服微信小程序源码系统&#xff0c;在外面现在的日常生活中&#xff0c;客服是不可或缺的岗位&#xff0c;下面我们一起来看看这款系统的功能介绍吧。下面是部分的代码截图&#xff1a; 在线客服系统源码微信小程序的功能主要包…

多场景通吃,INDEMIND视觉导航方案赋能服务机器人更多可能

打破场景限制&#xff0c;不一样的“斜杠青年”。 随着服务机器人不断进入到商场、超市、写字楼、酒店等新场景&#xff0c;场景的多样化和复杂度也在明显提升&#xff0c;由于场景的独特性&#xff0c;对于机器人的要求也千差万别&#xff0c;这意味机器人需要更强大的适应性…