[JAVA]定时任务之-Quartz使用篇

[JAVA]定时任务之-Quartz使用篇定时任务之-Quartz使用篇        Quartz是OpenSymphony开源组织在Jobscheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或EJBs。官方网站:http://www.opensymphon

大家好,又见面了,我是你们的朋友全栈君。                                                                                              
              定时任务之-Quartz使用篇

 

        Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。官方网站:http://www.opensymphony.com/quartz

 

相关Jar:
   quartz-all-1.6.0.jar
   jta.jar
   commons-logging-1.1.jar
   commons-collections3.2.jar

 

经过封装的管理类:

/** 
02. * 版权所有:华信软件 
03. * 项目名称:公用模块 
04. * 创建者: Wangdf 
05. * 创建日期: 2011-1-22 
06. * 文件说明: 定时任务管理类 
07. * 最近修改者:Wangdf 
08. * 最近修改日期:2011-1-22 
09. */  
10.package com.extjweb.quartz;  
11.  
12.import java.text.ParseException;  
13.  
14.import org.quartz.CronTrigger;  
15.import org.quartz.JobDetail;  
16.import org.quartz.Scheduler;  
17.import org.quartz.SchedulerException;  
18.import org.quartz.SchedulerFactory;  
19.import org.quartz.impl.StdSchedulerFactory;  
20.  
21./** 
22. * 定时任务管理类 
23. * 
24. * @author 王德封 
25. */  
26.public class QuartzManager {  
27.    private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();  
28.    private static String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME";  
29.    private static String TRIGGER_GROUP_NAME = "EXTJWEB_TRIGGERGROUP_NAME";  
30.  
31.    /** 
32.     * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 
33.     * 
34.     * @param jobName 
35.     *            任务名 
36.     * @param jobClass 
37.     *            任务 
38.     * @param time 
39.     *            时间设置,参考quartz说明文档 
40.     * @throws SchedulerException 
41.     * @throws ParseException 
42.     */  
43.    public static void addJob(String jobName, String jobClass, String time) {  
44.        try {  
45.            Scheduler sched = gSchedulerFactory.getScheduler();  
46.            JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, Class.forName(jobClass));// 任务名,任务组,任务执行类  
47.            // 触发器  
48.            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组  
49.            trigger.setCronExpression(time);// 触发器时间设定  
50.            sched.scheduleJob(jobDetail, trigger);  
51.            // 启动  
52.            if (!sched.isShutdown()){  
53.                sched.start();  
54.            }  
55.        } catch (Exception e) {  
56.            e.printStackTrace();  
57.            throw new RuntimeException(e);  
58.        }  
59.    }  
60.  
61.    /** 
62.     * 添加一个定时任务 
63.     * 
64.     * @param jobName 
65.     *            任务名 
66.     * @param jobGroupName 
67.     *            任务组名 
68.     * @param triggerName 
69.     *            触发器名 
70.     * @param triggerGroupName 
71.     *            触发器组名 
72.     * @param jobClass 
73.     *            任务 
74.     * @param time 
75.     *            时间设置,参考quartz说明文档 
76.     * @throws SchedulerException 
77.     * @throws ParseException 
78.     */  
79.    public static void addJob(String jobName, String jobGroupName,  
80.            String triggerName, String triggerGroupName, String jobClass, String time){  
81.        try {  
82.            Scheduler sched = gSchedulerFactory.getScheduler();  
83.            JobDetail jobDetail = new JobDetail(jobName, jobGroupName, Class.forName(jobClass));// 任务名,任务组,任务执行类  
84.            // 触发器  
85.            CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组  
86.            trigger.setCronExpression(time);// 触发器时间设定  
87.            sched.scheduleJob(jobDetail, trigger);  
88.        } catch (Exception e) {  
89.            e.printStackTrace();  
90.            throw new RuntimeException(e);  
91.        }  
92.    }  
93.  
94.    /** 
95.     * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) 
96.     * 
97.     * @param jobName 
98.     * @param time 
99.     */  
100.    public static void modifyJobTime(String jobName, String time) {  
101.        try {  
102.            Scheduler sched = gSchedulerFactory.getScheduler();  
103.            CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName, TRIGGER_GROUP_NAME);  
104.            if(trigger == null) {  
105.                return;  
106.            }  
107.            String oldTime = trigger.getCronExpression();  
108.            if (!oldTime.equalsIgnoreCase(time)) {  
109.                JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);  
110.                Class objJobClass = jobDetail.getJobClass();  
111.                String jobClass = objJobClass.getName();  
112.                removeJob(jobName);  
113.  
114.                addJob(jobName, jobClass, time);  
115.            }  
116.        } catch (Exception e) {  
117.            e.printStackTrace();  
118.            throw new RuntimeException(e);  
119.        }  
120.    }  
121.  
122.    /** 
123.     * 修改一个任务的触发时间 
124.     * 
125.     * @param triggerName 
126.     * @param triggerGroupName 
127.     * @param time 
128.     */  
129.    public static void modifyJobTime(String triggerName,  
130.            String triggerGroupName, String time) {  
131.        try {  
132.            Scheduler sched = gSchedulerFactory.getScheduler();  
133.            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerName, triggerGroupName);  
134.            if(trigger == null) {  
135.                return;  
136.            }  
137.            String oldTime = trigger.getCronExpression();  
138.            if (!oldTime.equalsIgnoreCase(time)) {  
139.                CronTrigger ct = (CronTrigger) trigger;  
140.                // 修改时间  
141.                ct.setCronExpression(time);  
142.                // 重启触发器  
143.                sched.resumeTrigger(triggerName, triggerGroupName);  
144.            }  
145.        } catch (Exception e) {  
146.            e.printStackTrace();  
147.            throw new RuntimeException(e);  
148.        }  
149.    }  
150.  
151.    /** 
152.     * 移除一个任务(使用默认的任务组名,触发器名,触发器组名) 
153.     * 
154.     * @param jobName 
155.     */  
156.    public static void removeJob(String jobName) {  
157.        try {  
158.            Scheduler sched = gSchedulerFactory.getScheduler();  
159.            sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器  
160.            sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器  
161.            sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务  
162.        } catch (Exception e) {  
163.            e.printStackTrace();  
164.            throw new RuntimeException(e);  
165.        }  
166.    }  
167.  
168.    /** 
169.     * 移除一个任务 
170.     * 
171.     * @param jobName 
172.     * @param jobGroupName 
173.     * @param triggerName 
174.     * @param triggerGroupName 
175.     */  
176.    public static void removeJob(String jobName, String jobGroupName,  
177.            String triggerName, String triggerGroupName) {  
178.        try {  
179.            Scheduler sched = gSchedulerFactory.getScheduler();  
180.            sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器  
181.            sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器  
182.            sched.deleteJob(jobName, jobGroupName);// 删除任务  
183.        } catch (Exception e) {  
184.            e.printStackTrace();  
185.            throw new RuntimeException(e);  
186.        }  
187.    }  
188.  
189.    /** 
190.     * 启动所有定时任务 
191.     */  
192.    public static void startJobs() {  
193.        try {  
194.            Scheduler sched = gSchedulerFactory.getScheduler();  
195.            sched.start();  
196.        } catch (Exception e) {  
197.            e.printStackTrace();  
198.            throw new RuntimeException(e);  
199.        }  
200.    }  
201.  
202.    /** 
203.     * 关闭所有定时任务 
204.     */  
205.    public static void shutdownJobs() {  
206.        try {  
207.            Scheduler sched = gSchedulerFactory.getScheduler();  
208.            if(!sched.isShutdown()) {  
209.                sched.shutdown();  
210.            }  
211.        } catch (Exception e) {  
212.            e.printStackTrace();  
213.            throw new RuntimeException(e);  
214.        }  
215.    }  
216.}  

改造Quartz的JobRunShell类的202行代码、使定时任务支持数据库全程事务以及数据库连接的关闭:

// execute the job  
02.try {  
03.    log.debug("Calling execute on job " + jobDetail.getFullName());  
04.    job.execute(jec);  
05.  
06.    // 2011/1/22 王德封 添加  
07.    DBUtil.commit();  
08.  
09.    endTime = System.currentTimeMillis();  
10.} catch (JobExecutionException jee) {  
11.    endTime = System.currentTimeMillis();  
12.    jobExEx = jee;  
13.  
14.    // 2011/1/22 王德封 添加  
15.    DBUtil.rollback();  
16.  
17.    getLog().info("Job " + jobDetail.getFullName() +  
18.            " threw a JobExecutionException: ", jobExEx);  
19.} catch (Throwable e) {  
20.    endTime = System.currentTimeMillis();  
21.    getLog().error("Job " + jobDetail.getFullName() +  
22.            " threw an unhandled Exception: ", e);  
23.    SchedulerException se = new SchedulerException(  
24.            "Job threw an unhandled exception.", e);  
25.    se.setErrorCode(SchedulerException.ERR_JOB_EXECUTION_THREW_EXCEPTION);  
26.    qs.notifySchedulerListenersError("Job ("  
27.            + jec.getJobDetail().getFullName()  
28.            + " threw an exception.", se);  
29.    jobExEx = new JobExecutionException(se, false);  
30.    jobExEx.setErrorCode(JobExecutionException.ERR_JOB_EXECUTION_THREW_EXCEPTION);  
31.  
32.    // 2011/1/22 王德封 添加  
33.    DBUtil.rollback();  
34.} finally {  
35.    // 2011/1/22 王德封 添加  
36.    DBUtil.closeCurrentConnection();  
37.}  

测试代码:

System.out.println("【系统启动】开始(每1秒输出一次)...");  
02.QuartzManager.addJob(job_name, job, "0/1 * * * * ?");  
03.//QuartzManager.addJob(job_name, job, "0 0/3 8-20 ? ? *");  
04.  
05.Thread.sleep(5000);  
06.System.out.println("【修改时间】开始(每2秒输出一次)...");  
07.QuartzManager.modifyJobTime(job_name, "10/2 * * * * ?");  
08.Thread.sleep(6000);  
09.System.out.println("【移除定时】开始...");  
10.QuartzManager.removeJob(job_name);  
11.System.out.println("【移除定时】成功");  
12.  
13.System.out.println("/n【再次添加定时任务】开始(每10秒输出一次)...");  
14.QuartzManager.addJob(job_name, job, "*/10 * * * * ?");  
15.Thread.sleep(60000);  
16.System.out.println("【移除定时】开始...");  
17.QuartzManager.removeJob(job_name);  
18.System.out.println("【移除定时】成功");  
[java] view plain copy
01.package com.extjweb.quartz;  
02.  
03.import java.util.Calendar;  
04.  
05.import org.quartz.Job;  
06.import org.quartz.JobExecutionContext;  
07.import org.quartz.JobExecutionException;  
08.  
09.public class TestJob implements Job {  
10.  
11.    @SuppressWarnings("deprecation")  
12.    public void execute(JobExecutionContext arg0) throws JobExecutionException {  
13.        System.out.println(Calendar.getInstance().getTime().toLocaleString()+ "★★★★★★★★★★★");  
14.    }  
15.  
16.}  

quartz 时间配置规则

格式: [秒] [分] [小时] [日] [月] [周] [年]

 序号 说明  是否必填  允许填写的值 允许的通配符
 1  秒  是  0-59    , – * /
 2  分  是  0-59   , – * /
 3 小时  是  0-23   , – * /
 4  日  是  1-31   , – * ? / L W
 5  月  是  1-12 or JAN-DEC   , – * /
 6  周  是  1-7 or SUN-SAT   , – * ? / L #
 7  年  否  empty 或 1970-2099  , – * /

通配符说明:


* 表示所有值. 例如:在分的字段上设置 “*”,表示每一分钟都会触发。


? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为”?” 具体设置为 0 0 0 10
* ?


- 表示区间。例如 在小时上设置 “10-12”,表示 10,11,12点都会触发。


, 表示指定多个值,例如在周字段上设置 “MON,WED,FRI” 表示周一,周三和周五触发


/ 用于递增触发。如在秒上面设置”5/15″ 表示从5秒开始,每增15秒触发(5,20,35,50)。在月字段上设置’1/3’所示每月1号开始,每隔三天触发一次。


L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于”7″或”SAT”。如果在”L”前加上数字,则表示该数据的最后一个。例如在周字段上设置”6L”这样的格式,则表示“本月最后一个星期五”


W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置”15W”,表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 “1W”,它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,”W”前只能设置具体的数字,不允许区间”-“).

小提示

‘L’和 ‘W’可以一组合使用。如果在日字段上设置”LW”,则表示在本月的最后一个工作日触发(一般指发工资

小提示

周字段的设置,若使用英文字母是不区分大小写的 MON 与mon相同.

       

常用示例:

 

0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)

0 0/5 14,18 * * ?

每天下午的 2点到2点59分(整点开始,每隔5分触发)
每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/158533.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • SpringBoot 源码编译「建议收藏」

    SpringBoot 源码编译「建议收藏」SpringBoot源码编译1、从GitHub上下载源码https://github.com/spring-projects/spring-boot/tree/2.1.x下载源码的下面有关于编译源码的介绍:SpringBoot官方建议使用./mvnwcleaninstall或者标准的mvncleaninstall命令来编译源代码,如果要使用标准的mvn命令的话…

  • volatile关键字作用

    volatile关键字作用一、作用简述内存可见性:保证变量的可见性:当一个被volatile关键字修饰的变量被一个线程修改的时候,其他线程可以立刻得到修改之后的结果。当一个线程向被volatile关键字修饰的变量写入数据的时候,虚拟机会强制它被值刷新到主内存中。当一个线程用到被volatile关键字修饰的值的时候,虚拟机会强制要求它从主内存中读取。 屏蔽JVM指令重排序(防止JVM编译源码生成class时使用重排序)…

  • 常用泰勒级数展开[通俗易懂]

    常用泰勒级数展开[通俗易懂]因为日常计算中经常需要做一些近似,而泰勒级数展开是其中最常用的一种,所以本篇整理了部分常见的(一元函数)泰勒公式展开

    2022年10月24日
  • 搭建邮件服务器,过程非常简单「建议收藏」

    搭建邮件服务器,过程非常简单,只需几个步骤即可。通常在Linux搭建邮件服务器是需要安装很多软件和配置文件的,所以我们可以使用一个开源邮件服务器软件来搭建的。

  • 二叉树以及常见面试题

    二叉树以及常见面试题

    2021年11月20日
  • mybatiscodehelperpro 2.9.6 怎么激活(注册激活)「建议收藏」

    (mybatiscodehelperpro 2.9.6 怎么激活)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html0VOERWDQ5R-eyJsa…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号