SpringBoot 整合 Quartz 定时任务框架

Springboot 整合 Quartz(定时任务框架) Quartz是 OpenSymphony 开源组织在 Job scheduling 领域又一个开源项目,完全由 Java 开发,可以用来执行定时任务,类似于 java.util.Timer。持久性作业 - 就是保持调度定时的状态;作业管理 - 对调度作业进行有效的管理; 阅读详情

一、简单聊一聊 Quartz

Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。

Quartz 其实就是通过一个调度线程不断的扫描数据库中的数据来获取到那些已经到点要触发的任务,然后调度执行它的。这个线程就是 QuartzSchedulerThread类。其run方法中就是quartz的调度逻辑。

另外,这是一个Demo,木有考虑并发、多任务执行等等状态的发生及处理情况,见谅。

1.1、Quartz 概念

Quartz 的几个核心概念

  1. Job

    表示一个工作,要执行的具体内容。此接口中只有一个方法

     void execute(JobExecutionContext context) 
    复制代码
  2. JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。

  3. Trigger 代表一个调度参数的配置,什么时候去调。

  4. Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

二、SpringBoot 使用 Quartz

2.1、基本步骤

基本步骤就那些,这篇也不是高大上讲原理和流程之类的,就是偏向实操,可能一些地方在代码中含有注释,就不再贴说明了~

基本:JDK 8、SpringBoot、MybatisPlus、Quartz

创建一个 SpringBoot 项目

导入相关依赖~

 <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.5.2</version>
     <relativePath/>
 </parent>
 ​
 <properties>
     <java.version>1.8</java.version>
     <maven.compiler.source>8</maven.compiler.source>
     <maven.compiler.target>8</maven.compiler.target>
 </properties>
 ​
 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-quartz</artifactId>
     </dependency>
     <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
     </dependency>
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
     </dependency>
     <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
         <version>3.4.1</version>
     </dependency>
 ​
     <dependency>
         <groupId>cn.hutool</groupId>
         <artifactId>hutool-all</artifactId>
         <version>5.1.4</version>
     </dependency>
     <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>fastjson</artifactId>
         <version>1.2.76</version>
     </dependency>
 </dependencies>
复制代码

项目结构:

2.2、执行 Quartz 需要的SQL文件

找到 quartz 需要的 sql 文件,在数据库中执行,这也是Quartz持久化的基础~

往下滑,找到你需要的sql文件即可。

执行完的结果:


在此基础上,我们再额外增加一张表,与我们可能有业务关联的信息整合,这啥啥允许为空,是方便我写测试~,并非正例

 DROP TABLE IF EXISTS `sys_quartz_job`;
 CREATE TABLE `sys_quartz_job`  (
   `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
   `create_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人',
   `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
   `del_flag` int(1) NULL DEFAULT NULL COMMENT '删除状态',
   `update_by` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '修改人',
   `update_time` datetime NULL DEFAULT NULL COMMENT '修改时间',
   `job_class_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务类名',
   `cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'cron表达式',
   `parameter` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '参数',
   `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
   `status` int(1) NULL DEFAULT NULL COMMENT '状态 0正常 -1停止',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;
 ​
复制代码

2.3、Controller

我们直接从controller说起吧,从上往下开发。

其实一旦牵扯到表的操作,我们无疑就是crud四件事。

 /**
  * @Description: 定时任务在线管理
  * @author nzc
  */
 @RestController
 @RequestMapping("/quartzJob")
 @Slf4j
 public class QuartzJobController {
 ​
     @Autowired
     private IQuartzJobService quartzJobService;
     @Autowired
     private Scheduler scheduler;
 ​
 ​
     @RequestMapping(value = "/list", method = RequestMethod.GET)
     public Result<?> queryPageList(QuartzJob quartzJob, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
         Page<QuartzJob> page = new Page<QuartzJob>(pageNo, pageSize);
         IPage<QuartzJob> pageList = quartzJobService.page(page);
         return Result.ok(pageList);
 ​
     }
 ​
     @RequestMapping(value = "/add", method = RequestMethod.POST)
     public Result<?> add(@RequestBody QuartzJob quartzJob) {
         List<QuartzJob> list = quartzJobService.findByJobClassName(quartzJob.getJobClassName());
         if (list != null && list.size() > 0) {
             return Result.error("该定时任务类名已存在");
         }
         quartzJobService.saveAndScheduleJob(quartzJob);
         return Result.ok("创建定时任务成功");
     }
 ​
     @RequestMapping(value = "/edit", method = RequestMethod.PUT)
     public Result<?> eidt(@RequestBody QuartzJob quartzJob) {
         try {
             quartzJobService.editAndScheduleJob(quartzJob);
         } catch (SchedulerException e) {
             log.error(e.getMessage(),e);
             return Result.error("更新定时任务失败!");
         }
         return Result.ok("更新定时任务成功!");
     }
 ​
     @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
     public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
         QuartzJob quartzJob = quartzJobService.getById(id);
         if (quartzJob == null) {
             return Result.error("未找到对应实体");
         }
         quartzJobService.deleteAndStopJob(quartzJob);
         return Result.ok("删除成功!");
 ​
     }
 ​
     @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
     public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
         if (ids == null || "".equals(ids.trim())) {
             return Result.error("参数不识别!");
         }
         for (String id : Arrays.asList(ids.split(","))) {
             QuartzJob job = quartzJobService.getById(id);
             quartzJobService.deleteAndStopJob(job);
         }
         return Result.ok("删除定时任务成功!");
     }
 ​
     /**
      * 暂停定时任务
      * @param jobClassName
      */
     @GetMapping(value = "/pause")
     public Result<Object> pauseJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
         QuartzJob job = null;
         try {
             job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
             if (job == null) {
                 return Result.error("定时任务不存在!");
             }
             scheduler.pauseJob(JobKey.jobKey(jobClassName.trim()));
         } catch (SchedulerException e) {
             throw new MyException("暂停定时任务失败");
         }
         job.setStatus(CommonConstant.STATUS_DISABLE);
         quartzJobService.updateById(job);
         return Result.ok("暂停定时任务成功");
     }
 ​
     /**
      * 恢复定时任务
      * @param jobClassName
      */
     @GetMapping(value = "/resume")
     public Result<Object> resumeJob(@RequestParam(name = "jobClassName", required = true) String jobClassName) {
         QuartzJob job = quartzJobService.getOne(new LambdaQueryWrapper<QuartzJob>().eq(QuartzJob::getJobClassName, jobClassName));
         if (job == null) {
             return Result.error("定时任务不存在!");
         }
         quartzJobService.resumeJob(job);
         //scheduler.resumeJob(JobKey.jobKey(job.getJobClassName().trim()));
         return Result.ok("恢复定时任务成功");
     }
 ​
     /** 通过id查询*/
     @RequestMapping(value = "/queryById", method = RequestMethod.GET)
     public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
         QuartzJob quartzJob = quartzJobService.getById(id);
         return Result.ok(quartzJob);
     }
 }
 ​
复制代码

2.4、Service 划重点

 public interface IQuartzJobService extends IService<QuartzJob> {
 ​
     List<QuartzJob> findByJobClassName(String jobClassName);
 ​
     boolean saveAndScheduleJob(QuartzJob quartzJob);
 ​
     boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException;
 ​
     boolean deleteAndStopJob(QuartzJob quartzJob);
 ​
     boolean resumeJob(QuartzJob quartzJob);
 }
 ​
复制代码

其中最主要的实现都是在这里:

 @Slf4j
 @Service
 public class QuartzJobServiceImpl extends ServiceImpl<QuartzJobMapper, QuartzJob> implements IQuartzJobService {
 ​
     @Autowired
     private QuartzJobMapper quartzJobMapper;
 ​
     @Autowired
     private Scheduler scheduler;
 ​
     @Override
     public List<QuartzJob> findByJobClassName(String jobClassName) {
         return quartzJobMapper.findByJobClassName(jobClassName);
     }
 ​
     /**保存&启动定时任务*/
     @Override
     public boolean saveAndScheduleJob(QuartzJob quartzJob) {
         if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
             // 定时器添加
             this.schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
         }
         // DB设置修改
         return this.save(quartzJob);
     }
 ​
     /**恢复定时任务 */
     @Override
     public boolean resumeJob(QuartzJob quartzJob) {
         schedulerDelete(quartzJob.getJobClassName().trim());
         schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
         quartzJob.setStatus(CommonConstant.STATUS_NORMAL);
         return this.updateById(quartzJob);
     }
 ​
     /**编辑&启停定时任务 @throws SchedulerException */
     @Override
     public boolean editAndScheduleJob(QuartzJob quartzJob) throws SchedulerException {
         if (CommonConstant.STATUS_NORMAL.equals(quartzJob.getStatus())) {
             schedulerDelete(quartzJob.getJobClassName().trim());
             schedulerAdd(quartzJob.getJobClassName().trim(), quartzJob.getCronExpression().trim(), quartzJob.getParameter());
         }else{
             scheduler.pauseJob(JobKey.jobKey(quartzJob.getJobClassName().trim()));
         }
         return this.updateById(quartzJob);
     }
 ​
     /**删除&停止删除定时任务*/
     @Override
     public boolean deleteAndStopJob(QuartzJob job) {
         schedulerDelete(job.getJobClassName().trim());
         return this.removeById(job.getId());
     }
 ​
     /** 添加定时任务*/
     private void schedulerAdd(String jobClassName, String cronExpression, String parameter) {
         try {
             // 启动调度器
             scheduler.start();
 ​
             // 构建job信息
             JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName).usingJobData("parameter", parameter).build();
 ​
             // 表达式调度构建器(即任务执行的时间)
             CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
 ​
             // 按新的cronExpression表达式构建一个新的trigger
             CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName).withSchedule(scheduleBuilder).build();
 ​
             scheduler.scheduleJob(jobDetail, trigger);
         } catch (SchedulerException e) {
             throw new MyException("创建定时任务失败", e);
         } catch (RuntimeException e) {
             throw new MyException(e.getMessage(), e);
         }catch (Exception e) {
             throw new MyException("后台找不到该类名:" + jobClassName, e);
         }
     }
 ​
     /** 删除定时任务*/
     private void schedulerDelete(String jobClassName) {
         try {
             /*使用给定的键暂停Trigger 。*/
             scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName));
             /*从调度程序中删除指示的Trigger */
             scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName));
             /*从 Scheduler 中删除已识别的Job - 以及任何关联的Trigger */
             scheduler.deleteJob(JobKey.jobKey(jobClassName));
         } catch (Exception e) {
             log.error(e.getMessage(), e);
             throw new MyException("删除定时任务失败");
         }
     }
     
     private static Job getClass(String classname) throws Exception {
         Class<?> class1 = Class.forName(classname);
         return (Job) class1.newInstance();
     }
 }
 ​
复制代码
 @Mapper
 public interface QuartzJobMapper extends BaseMapper<QuartzJob> {
     @Select("select * from  sys_quartz_job  where job_class_name = #{jobClassName}")
     public List<QuartzJob> findByJobClassName(@Param("jobClassName") String jobClassName);
 }
复制代码

2.5、实体类

 @Data
 @TableName("sys_quartz_job")
 public class QuartzJob implements Serializable {
 ​
     @TableId(type = IdType.ID_WORKER_STR)
     private String id;
 ​
     private String createBy;
 ​
     private String updateBy;
 ​
     /**任务类名*/
     private String jobClassName;
     
     /** cron表达式 */
     private String cronExpression;
     
     /**  参数*/
     private String parameter;
 ​
     private String description;
     /** 状态 0正常 -1停止*/
     private Integer status;
     
     @TableLogic
     private Integer delFlag;
 ​
     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @TableField(fill = FieldFill.INSERT)
     private Date createTime;
 ​
     @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @TableField(fill = FieldFill.INSERT_UPDATE)
     private Date updateTime;
 }
复制代码

另外在这里顺带补充一下,本项目在yml中配置quartz,如下:

spring:
  ## quartz定时任务,采用数据库方式
  quartz:
    job-store-type: jdbc
复制代码

其他很杂的一些MybatisPlus 相关和一些公共类,从仓库中拿一下就好github源码

2.6、简单的 Job 案例

如果调度器要执行任务,首先得要有一个任务相关滴类。

写了两个平常的案例,一个是不带参数的,一个是带参数的。

/**
 * 不带参的简单定时任务
 * @Author nzc
 */
@Slf4j
public class SampleJob implements Job {

	@Override
	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

		log.info(String.format("Ning zaichun的 普通定时任务 SampleJob !  时间:" + new Date()));
	}
}
复制代码

带参数的

 /**
  * 带参数的简单的定时任务
  * @Author nzc
  */
 @Slf4j
 public class SampleParamJob implements Job {
 ​
     /**
      * 若参数变量名修改 QuartzJobController中也需对应修改
      */
     private String parameter;
 ​
     public void setParameter(String parameter) {
         this.parameter = parameter;
     }
 ​
     @Override
     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
         log.info(String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob !   时间:" + LocalDateTime.now(), this.parameter));
     }
 }
 ​
复制代码

2.7、那么该如何使用呢?

启动项目,让我们拿起来postman来测试吧,康康该如何使用,数据表在使用的时候,又有怎么样的变化~

我们直接来测试添加定时任务的接口,先来个不用参数的吧

 {
     "createBy": "nzc",
     "jobClassName": "com.nzc.quartz.job.SampleJob",
     "cronExpression": "0/10 * * * * ? ",
     "description": "每十秒执行一次",
     "status": "0"
 }
复制代码

添加完之后就已经在执行了。

此时我们将项目停止,重新启动~

调度器也会主动去检测任务信息,如果有,就会开始执行。

我们再来测测带有参数的

也是可以成功的,并且也是按照我们设定的时间执行的

其他的接口也是同样如此,根据接口的设定,将参数传入即可源码

后记

本文不牵扯到过多的内容,就是一篇普通的入门的使用教程。

后续在更文的时候,再打算说一说它的流程。

我觉得内部的执行流程和机制才是有趣的,Debug的时候,你会发现很多很多的奥妙~

不过想要探索之前,还是需要学会如何使用才行~

SpringBoot整合Quartz 目录`Quartz` 简介 Quartz 简介 Quartz 是一款功能强大的开源任务调度框架,几乎可以集成到任何 Java 应用程序中(小到单机应用,大到分布式应用)。Quartz 可用于创建简单或复杂的任务调度,用以执行数以万计的任务。任务被定义为标准化的 Java 组件,Java 编写的任务都可以被执行 Quartz 是一个任务日程管理系统,一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统 Quartz 用一个小 Java 库发布文件(.jar文件),这个库文件包含了所 阅读详情

相关推荐

看一篇搞懂quartz框架、spring boot整合quartz实现定时任务动态配置,附代码(保姆级教程二)

spring boot、quartz

zhangfuping123456789的博客 4785

springboot整合quartz

springboot集成调度框架quartz,各类定时框架比较

太上码农 1万+

常用的集成TTL门电路

本篇主要分析了常用的逻辑门电路与非门,详细分析了电源原理。值得收藏。

ManagerUser的博客 5089

定时任务之Springboot整合Quartz详解

Springboot整合Quartz详解

qq_45087487的博客 1万+

三维变换矩阵实战——三维点云的旋转、缩放、镜像、错切、平移、正交投影

旋转矩阵:右边矩阵是点云的原始坐标,左边的是旋转矩阵可视化:绕x轴旋转90度。

weixin_43850909的博客 8231

手把手教你用DSP28335的PWM移相功能搞定双有源桥DAB(附完整代码)

本文详细解析了DSP28335的PWM移相功能在双有源桥DAB中的应用,包括ePWM模块的配置、移相时序原理及实战代码。通过精确的移相控制,实现DAB的高效运行和软开关,适用于车载充电机、储能系统等场景。附完整代码,助力开发者快速掌握硬件级移相技术。

weixin_30632089的博客 423

SpringBoot整合Quartz 定时任务框架

SpringBoot整合Quartz 定时任务框架 1.Quartz介绍以及Quartz的使用思路 参考文档:https://blog.youkuaiyun.com/noaman_wgs/article/details/80984873 1.1.Quartz的介绍 ​ Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做

qq_42191775的博客 306

Qt数据导出实战:从SQLite到CSV的完整流程(附内存优化技巧)

本文详细介绍了在Qt框架下,将SQLite数据库中的数据高效导出为CSV格式的完整流程。针对大数据量场景,重点分享了分块读取、流式写入等内存优化技巧,有效解决了嵌入式或资源受限环境中导出功能的内存占用与性能瓶颈问题,并提供了健壮的代码实现方案。

weixin_29313547的博客 342

springboot整合quartz框架_spring boot整合quartz实现通过页面操作管理定时任务

spring boot整合quartz实现通过页面操作管理定时任务说起quartz,大家肯定就会想起那些繁杂的配置,复杂的代码。但是如果项目中要用到定时任务的话,除了quartz似乎也想不出来别的框架了,毕竟人家做的确实优秀。但是在spring boot中使用quartz,再也不用像以前那么大费周章了。spring boot将quartz的实现细节全都给你封装好了,调用定时任务是需要一个小小的注解...

weixin_39662263的博客 165

基于555定时器的D类功放设计:从PWM原理到无反馈电路实践

D类功放(数字功放)是一种高效率的音频放大技术,其核心原理是脉冲宽度调制(PWM)。它将输入的模拟音频信号转换为一系列高速开关的脉冲,通过控制功率开关管(如MOSFET)的通断,再经低通滤波器还原放大后的音频。相比传统AB类功放,其转换效率通常超过90%,显著降低了热能损耗。这项技术在追求高能效和小型化的现代音频设备中价值凸显,广泛应用于有源音箱、汽车音响和便携式设备。本文聚焦于一种独特的实现方案:以经典的555定时器芯片为核心,构建一个无整体负反馈的D类功放。通过剖析其PWM调制器、FET电压-电流转换级

weixin_30162121的博客 226

【电子元件篇】电力电子中的变压器原理、作用、选型与测量指南-超简单解读

变压器虽小,却是电力电子的 “关键纽带”——从识别符号型号,到理解 “传交流隔直流” 的特点,再到按用途选参数、用万用表检测,只要抓住 “场景对应核心” 的逻辑,就能轻松掌握它的用法。

2301_81299416的博客 3031

看一篇搞懂quartz框架、什么是quartz定时任务、spring boot整合quartz框架实现定时任务,附代码(保姆级教程一)

spring boot、quartz

zhangfuping123456789的博客 4192

CiteSpace关键词聚类图谱含义详细解析

CiteSpace关键词聚类图谱含义详细解析 回顾上一次推文:CiteSpace关键词共现图谱含义详细解析 其中有一句: 当你人工已经可以很容易的进行归纳后,就不需要再利用CiteSpace聚类功能啦。 我们来看一下上次推文做出来的关键词共现图谱: 人工不好归纳!那怎么聚类呢? 此时便可使用CiteSpace的聚类功能啦! 如下所示:我们可以清晰地看到上边的关键词共现网络聚成了一个个不规则区域...

qq_39974284的博客 6万+

定时任务框架Quartz原理和整合springboot

文章目录定时任务框架Quartz介绍二、Quartz Demo搭建三、Quartz核心详解四、Quartz流程和原理五、Quartz持久化任务和锁机制六、Springboot整合Quartz实现动态定时任务 定时任务框架Quartz介绍 #一、 什么是Quartz (1)首先我们需要定义实现一个定时功能的接口,我们可以称之为Task(或Job),如定时发送邮件的task(Job),重启机器的task(Job),优惠券到期发送短信提醒的task(Job),实现接口如下: [外链图片转存失败,源站可能有防盗链机

weixin_44308214的博客 1215

Lumerical 教程,包含作者个人理解及相关设计案例 (目前共计184篇,持续更新中)

4138。

u011699626的博客 1632

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

SpringBoot整合Quartz定时任务框架

什么是Quartz? Quartz是定时任务框架。是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能: 持久性作业 - 就是保持调度定时的状态; 作业管理 - 对调度作业进行有效的管理; 大部分公司都会用到定时任务这个功能。 拿火车票购票来说,当你下单后,后台就会插入一条待支付的task(job),一般是30分钟,超过30min后就会执行这个

小小周的博客 368

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

上一篇: Alibaba架构师纯手工打造神仙级“2022版Java面试手册”
下一篇: 如何优雅的用Redis作为Mybatis的二级缓存?
程序员职业指南
博客等级 码龄4年 2138粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值