一般的系统都会有一些定时任务,那么我们将这个定时任务封装起来,只要系统需要添加定时任务时,只需调用此方法传入所需要的值即可完成定时任务。  自己自学整理的一些随笔

1.首先对周期粒度进行封装

public enum GranularityPeriod{
UNSPECIFIED(0), ONE_MIN(1), TWO_MINS(2), THREE_MINS(3), FOUR_MINS(4), FIVE_MINS(5), SIX_MINS(6), TEN_MINS(10), TWELVE_MINS(
12), FIFTEEN_MINS(15), TWENTY_MINS(20), THIRTY_MINS(30), ONE_HOUR(60), TWO_HOURS(120), THREE_HOURS(180), FOUR_HOURS(
240), SIX_HOURS(360), EIGHT_HOURS(480), TWELVE_HOURS(720), TWENTY_FOUR_HOURS(1440);
private final int value; GranularityPeriod(int value) {
this.value = value;
} public int value() {
return this.value;
} public static GranularityPeriod getGranularityPeriod(int value) { switch (value) {
case 0:
return UNSPECIFIED;
case 1:
return ONE_MIN;
case 2:
return TWO_MINS;
case 3:
return THREE_MINS;
case 4:
return FOUR_MINS;
case 5:
return FIVE_MINS;
case 6:
return SIX_MINS;
case 10:
return TEN_MINS;
case 12:
return TWELVE_MINS;
case 15:
return FIFTEEN_MINS;
case 20:
return TWENTY_MINS;
case 30:
return THIRTY_MINS;
case 60:
return ONE_HOUR;
case 120:
return TWO_HOURS;
case 180:
return THREE_HOURS;
case 240:
return FOUR_HOURS;
case 360:
return SIX_HOURS;
case 480:
return EIGHT_HOURS;
case 720:
return TWELVE_HOURS;
case 1440:
return TWENTY_FOUR_HOURS;
}
throw new IllegalArgumentException("NOT GranularityPeriod matched the argument!");
} }

2.对同步方式进行封装

public enum DateCycle {
BY_DAY, BY_WEEK, BY_MONTH;
}
public class DayOfWeek {
public static String getDay(int i) { switch (i) {
case 0:
return "Sun";
case 1:
return "Mon";
case 2:
return "Tue";
case 3:
return "Wed";
case 4:
return "Thu";
case 5:
return "Fri";
case 6:
return "Sat";
}
throw new IllegalArgumentException("NOT day matched the argument!");
}
}

3.设置需要定时同步的周期对象

(1)同步任务的任务名 跟 任务组名进行封装

public class JobInfo {
private String jobName;
private String jobGroupName; public JobInfo(String jobName,String jobGroupName){
this.jobName = jobName;
this.jobGroupName = jobGroupName;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroupName() {
return jobGroupName;
}
public void setJobGroupName(String jobGroupName) {
this.jobGroupName = jobGroupName;
}
}

(2)定时任务的对象设定,并指定任务名 任务组名

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map; public class TimingSync implements Serializable {
private static final long serialVersionUID = 1L;
public static final Integer SWTICH_OFF =0;
public static final Integer BY_DAY =1;
public static final Integer BY_WEEK =2;
public static final Integer BY_MONTH =3;
public static final Integer TYPE_IOPS =0;
//public static final String IOPS_JOB_NAME ="my_sync";
//public static final String IOPS_JOB_GROUPNAME ="my_group";
/**
* 0--- 定时同步开关关闭
* 1--- 按天定时
* 2--- 按周定时
* 3--- 按月定时
*/
private Integer status;
private String day;//按月定时时填写该字段从1开始,第0位代表第一天,如1110101 代表某月的1号,2号,3号,5号,7号
private String week;//按周定时时填写该字段从周日开始一共7位0000000,如0100001 代表周一和周六
private Integer businessType;// 定时任务的业务类型,0代表my_sync,可以扩展其他业务
private String synctime = "00:00:00"; public final static Map<Integer,EbsJobInfo> JOB_TYPE_NAME_MAP = new HashMap<Integer,JobInfo>();
static {
JOB_TYPE_NAME_MAP.put(TYPE_MY, new EbsJobInfo("my_sync", "my_group"));
} public String getWeek() {
return week;
} public void setWeek(String week) {
this.week = week;
} public String getDay() {
return day;
} public void setDay(String day) {
this.day = day;
} public Integer getStatus() {
return status;
} public void setStatus(Integer status) {
this.status = status;
} public String getSynctime() {
return synctime;
} public void setSynctime(String synctime) {
this.synctime = synctime;
} @Override
public String toString() {
return "TimingSync [businessType="+businessType+", status=" + status + ", week=" + week + ", day=" + day + ", synctime=" + synctime + "]";
} public Integer getBusinessType() {
return businessType;
} public void setBusinessType(Integer businessType) {
this.businessType = businessType;
} }

4.封装调度机信息,用于存储所需要的同步周期方式

public class ScheduleInfo implements Serializable, Cloneable {

    private static final long serialVersionUID = 3258130271374160953L;
private String quartzName; private String quartzGroup;
private String executorId;
private Date startTime;
private Date endTime;
private Date tiggerTime;
private String weekDays, monthDays;
private DateCycle dateCycle = DateCycle.BY_DAY; public String getWeekDays() {
return weekDays;
} public void setWeekDays(String weekDays) {
this.weekDays = weekDays;
} public String getMonthDays() {
return monthDays;
} public void setMonthDays(String monthDays) {
this.monthDays = monthDays;
} public Date getEndTime() {
return endTime;
} public void setEndTime(Date endTime) {
this.endTime = endTime;
} public Date getStartTime() {
return startTime;
} public void setStartTime(Date startTime) {
this.startTime = startTime;
} public String getExecutorId() { return executorId;
} public void setExecutorId(String executorId) { this.executorId = executorId;
} public String getQuartzGroup() { return quartzGroup;
} public void setQuartzGroup(String quartzGroup) { this.quartzGroup = quartzGroup;
} public String getQuartzName() { return quartzName;
} public void setQuartzName(String quartzName) { this.quartzName = quartzName;
}
private GranularityPeriod granularityPeriod = GranularityPeriod.ONE_MIN; public static ScheduleInfo newInstance(Date startTime, Date stopTime) { ScheduleInfo schedule = new ScheduleInfo(); schedule.startTime = startTime;
schedule.endTime = stopTime; return schedule;
} public Date getTiggerTime() {
return tiggerTime;
} public void setTiggerTime(Date tiggerTime) {
this.tiggerTime = tiggerTime;
} public Object clone() throws CloneNotSupportedException {
ScheduleInfo clone = (ScheduleInfo) super.clone();
if(null == this.startTime){
clone.startTime = null;
}
else{
clone.startTime = (Date) this.startTime.clone();
}
if(null == this.endTime){
this.endTime = null;
}
else{
clone.endTime = (Date) this.endTime.clone();
}
return clone;
} public GranularityPeriod getGranularityPeriod() {
return granularityPeriod;
} public void setGranularityPeriod(GranularityPeriod granularityPeriod) {
this.granularityPeriod = granularityPeriod;
} public DateCycle getDateCycle() {
return dateCycle;
} public void setDateCycle(DateCycle dateCycle) {
this.dateCycle = dateCycle;
}
}

5.封装方法生成设定的所期望的同步规则

public class CronTriggerUtil {
// 所需要的符号
/**
* Comment for <code>SPACE</code>
*/
public final static String SPACE = " "; /**
* Comment for <code>ZERO</code>
*/
public final static String ZERO = "0"; /**
* Comment for <code>SUB</code>
*/
public final static String SUB = "-"; /**
* Comment for <code>DIV</code>
*/
public final static String DIV = "/"; /**
* Comment for <code>ASTERISK</code>
*/
public final static String ASTERISK = "*"; /**
* Comment for <code>INTERROGATION</code>
*/
public final static String INTERROGATION = "?"; /**
* Comment for <code>COMMA</code>
*/
public final static String COMMA = ","; /**
* 根据传入的自定义的定时方式生成trigger所认识的定时任务规则
*
*/
public String toCronExpr(ScheduleInfo schedule) {
String expr = toTimeCronExpr(schedule) + toDateCronExpr(schedule);
return expr;
} /**
* 获得时间表达式,分为3中情况处理,分别是:没有时间段,有一个时间段,有多个时间段,
*/
private String toTimeCronExpr(ScheduleInfo schedule) { StringBuilder result = new StringBuilder(); // 用开始时间作为启动时间
Date date = schedule.getStartTime();
Date currentDate = new Date(System.currentTimeMillis());
if(date == null){
date = currentDate;
}
int setSecond = getStartSeconds(date);
if(setSecond < 59){//59+1的话会导致开始时间大于触发时间,定时任务会延迟一个周期触发,所以这里去掉59s时的加1操作
setSecond = setSecond+1;
}
if(setSecond == 60){
setSecond = 0;
} result.append(setSecond).append(SPACE); // 特殊处理,在周期为天,判断tiggerTime。24小时
if(schedule.getGranularityPeriod().value() == 1440){
// date = new Date(date.getTime() + 1000 * 60 * 60);
result.append(getStartMinute(date)).append(SPACE).append(getStartHour(date)).append(SPACE); }
// 特殊处理,在周期为天,判断tiggerTime。12小时
else if(schedule.getGranularityPeriod().value() == 720){
// date = new Date(date.getTime() + 1000 * 60 * 60);
result.append(getStartMinute(date)).append(SPACE);
if(schedule.getEndTime() != null && schedule.getEndTime().getTime() - date.getTime() < 43200000){
result.append(getStartHour(date)).append(SPACE);
}
else{
result.append(getStartHour(date) + COMMA + getEndHour(date)).append(SPACE);
}
}
// 立即执行的情况
else if(schedule.getGranularityPeriod().value() == 0){
date = new Date(date.getTime() + 1000 * 60);
result.append(getStartMinute(date)).append(SPACE).append(getStartHour(date)).append(SPACE);
}
// 普通情况
else{
result.append(0).append(DIV).append(getValue(schedule.getGranularityPeriod())).append(SPACE)
.append(getHourTime(schedule)).append(SPACE);
} return result.toString();
} /**
* trigger time return start Seconds
*/
private int getStartSeconds(Date date) { Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.SECOND);
} /**
* trigger time return start miniute
*/
private int getStartMinute(Date date) { Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.MINUTE);
} /**
* trigger time return start hour
*/
private int getStartHour(Date date) { Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.HOUR_OF_DAY);
} /**
* 获得日期的月数
*/
private int getMonth(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.MONTH) + 1;
} /**
* 获得日期的年数
*/
private int getYear(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.YEAR);
} /**
* 获得日期的天数
*/
private int getDay(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
return cal.get(Calendar.DAY_OF_MONTH);
} /**
* 获取12小时的结束时间
*
* @param startHour
* @return
*/
private int getEndHour(Date date) {
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
int hour = cal.get(Calendar.HOUR_OF_DAY);
if(hour < 12){
return 12 + hour;
}
return (12 + hour) % 24;
} /**
* 得到循环周期为月的具体的号数,假如输入的是1,那么就加入他所在位置的号数
* exp: input = "111110001001" output= "1,2,3,4,5,9,12";
*/
private Object getByMonthDays(ScheduleInfo schedule) { String days = schedule.getMonthDays();
StringBuilder builder = new StringBuilder(); for (int i = 0; i < days.length(); i++){ if("1".equals(days.charAt(i) + "")){ builder.append(i + 1).append(COMMA);
}
}
String temp = builder.toString();
if(temp.endsWith(COMMA)){ return temp.substring(0, temp.length() - 1);
}
return temp;
} /**
* 得到循环周期为周的具体的星期天数, 例如输入的是1,
* 那么就加入他所在位置的星期数 exp: input = "0001000"; output= "Wed";
*/
public String getByWeekDays(ScheduleInfo schedule) { String days = schedule.getWeekDays();
StringBuilder builder = new StringBuilder(); for (int i = 0; i < days.length(); i++){ if("1".equals(days.charAt(i) + "")){ builder.append(DayOfWeek.getDay(i)).append(COMMA);
}
}
String temp = builder.toString();
if(temp.endsWith(COMMA)){ return temp.substring(0, temp.length() - 1);
}
return temp;
} private String toDateCronExpr(ScheduleInfo schedule) { StringBuilder result = new StringBuilder(); if(schedule.getGranularityPeriod().value() == 0){
Date date = schedule.getStartTime();
if(date == null)
date = new Date(System.currentTimeMillis());
result.append(getDay(date)).append(SPACE).append(getMonth(date)).append(SPACE).append(INTERROGATION)
.append(SPACE).append(getYear(date));
}
else if("BY_DAY".equals(schedule.getDateCycle().toString())){ result.append(ASTERISK).append(SPACE).append(ASTERISK).append(SPACE).append(INTERROGATION);
}
else if("BY_WEEK".equals(schedule.getDateCycle().toString())){ result.append(INTERROGATION).append(SPACE).append(ASTERISK).append(SPACE).append(getByWeekDays(schedule));
}
else if("BY_MONTH".equals(schedule.getDateCycle().toString())){ result.append(getByMonthDays(schedule)).append(SPACE).append(ASTERISK).append(SPACE).append(INTERROGATION);
} return result.toString();
} /**
* 由于跨多个小时quartz不认,最大只能以小时为单位,所以只能对其进行转换。
* 如:0 0/240 * * ? 想以每天为单位,每隔4个小时触发一次,但情况还是每个小时触发一次。 只有将其改为 0 0/60
* 0,4,8,12,16,20
*/
public String getHourTime(ScheduleInfo schedule) { int hourUnit = schedule.getGranularityPeriod().value(); String builder = null; if(hourUnit == 120){ builder = "0,2,4,6,8,10,12,14,16,18,20,22";
}
else if(hourUnit == 180){ builder = "0,3,6,9,12,15,18,21";
}
else if(hourUnit == 240){ builder = "0,4,8,12,16,20";
}
else if(hourUnit == 360){ builder = "0,6,12,18";
}
else if(hourUnit == 480){ builder = "0,8,16";
}
else if(hourUnit == 720){ builder = "0,12";
}else{ builder = "*";
}
return builder;
} /**
* 由于quartz的表达式最大支持为60分钟,因此,大于60就当作是60
*/
public String getValue(GranularityPeriod value) { if(value.value() > 60){ return "60";
} return value.value() + "";
} }

6.设置定时任务(定时时间所要执行的任务)

public class QuartzJob implements Job{

    @Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
for(int i = 0; i < 5;i = i + 1){
for(int j = 0; j < 3; j++){
System.out.println("数组中的平均值"+j);
}
System.out.println("1111111");
}
} }

7.将定时任务添加到JobDetail中

public class QuartzManager {
private static SchedulerFactory schedulerFactory = new StdSchedulerFactory(); /**
* @Description: 添加一个定时任务
*
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param jobClass 任务
* @param cron 时间设置,参考quartz说明文档
*/
@SuppressWarnings({ "rawtypes" })
public static void addJob(String jobName, String jobGroupName, Class jobClass, ScheduleInfo scheduleInfo) {
try {
//调度器
Scheduler sched = schedulerFactory.getScheduler();
// 任务名,任务组,任务执行类
JobDetail jobDetail= new JobDetail(jobName,jobGroupName,jobClass); // 创建Trigger对象 触发器
CronTrigger cronTrigger = new CronTrigger(jobName,jobGroupName);
cronTrigger.setStartTime(scheduleInfo.getStartTime());
cronTrigger.setCronExpression(new CronTriggerUtil().toCronExpr(scheduleInfo));
cronTrigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING); sched.scheduleJob(jobDetail, cronTrigger); // 启动
if (!sched.isShutdown()) {
sched.start();
} } catch (Exception e) {
}
} /**
* @Description: 开始一个定时任务
*/
public static void startTimingJob(Integer jobType){
UDCTimingSync timeSyncObj = new UDCTimingSync();
timeSyncObj.setStatus(1);
timeSyncObj.setSynctime("20:57:00");
ScheduleInfo schedule_info = new ScheduleInfo();
if(null == timeSyncObj.getStatus()){
return;
}
if(timeSyncObj.getStatus().equals(UDCTimingSync.SWTICH_OFF)){
return;
}
if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_DAY)){//按天
schedule_info.setDateCycle(DateCycle.BY_DAY);
schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
}else if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_WEEK)){//按周
schedule_info.setDateCycle(DateCycle.BY_WEEK);
schedule_info.setWeekDays(timeSyncObj.getWeek().toString());
schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
}else if(timeSyncObj.getStatus().equals(UDCTimingSync.BY_MONTH)){
schedule_info.setDateCycle(DateCycle.BY_MONTH);
schedule_info.setMonthDays(timeSyncObj.getDay().toString());
schedule_info.setGranularityPeriod(GranularityPeriod.TWENTY_FOUR_HOURS);
schedule_info.setStartTime(QuartzManager.getStartTime(timeSyncObj.getSynctime()));
} QuartzManager.addJob(UDCTimingSync.JOB_TYPE_NAME_MAP.get(jobType).getJobName(),
UDCTimingSync.JOB_TYPE_NAME_MAP.get(jobType).getJobGroupName(), QuartzJob.class, schedule_info);
} /**
* @Description: 将传入的时间转成日历标准时间
*/
public static Date getStartTime(String limitBeginTime) {
Calendar calendar = Calendar.getInstance(); // 获取当前时间
Date currentDate = new Date(System.currentTimeMillis());
calendar.setTime(currentDate);
Date now = calendar.getTime(); String[] begins = limitBeginTime.split(":");
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(begins[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(begins[1]));
calendar.set(Calendar.SECOND, Integer.parseInt(begins[2]));
Date beginTime = calendar.getTime(); // 当开始时间小于或者等于当前时间,则将日期增加一天
boolean isGreater = beginTime.after(now);
if (!isGreater) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
} return calendar.getTime();
}
}

8.测试类 调用定时任务

public class QuartzTest {

    public static void main(String[] args) {

        initJobs();
}
/**
* @Description: 调用定时任务组,传入定时任务组名
*/
private static void initJobs(){
QuartzManager.startTimingJob(UDCTimingSync.TYPE_IOPS);
System.out.print("now time is"+new Date(System.currentTimeMillis()));
}
}

最新文章

  1. Mongodb profile(慢查询日志)
  2. Apache, Tomcat, JK Configuration Example
  3. Session Tracking Approaches
  4. [vijos1427]机密信息
  5. SAP物料批次管理配置及操作手册(轉載)
  6. Linux下设置定期执行脚本
  7. AndroidStudio支持新的NDK的操作使用
  8. [转] Understanding Twitter Bootstrap 3
  9. 怎样调整XenServer下面Linux虚拟机的磁盘大小
  10. java7 - JDK
  11. hdu5945 Fxx and game
  12. vue2.0 带头冲锋(打包时,小心萝卜坑)
  13. pytorch错误:RuntimeError: received 0 items of ancdata解决
  14. 浅谈Web开发中的定时任务
  15. 路由信息对象Route之属性query和params的区别
  16. jQuery实现input框输入值动态搜索
  17. Markdown基础(内含:锚点使用,使用HTML,新页面跳转,目录生成)
  18. JS笔记(二):对象
  19. 前端异步的一种方法库:axios
  20. 【GRPC】GRPC-负载均衡

热门文章

  1. ubuntu学习笔记
  2. win10 1803版本unable to start ssh-agent service, error :1058
  3. 那些按烂的Linux命令集合贴
  4. ssh 框架整合事,使用注解,action提示找不到
  5. Error:Execution failed for task &#39;:app:preDebugAndroidTestBuild&#39;. &gt; Conflict with dependency &#39;com.android.support:support-annotations&#39; in project &#39;:app&#39;. Resolved versions for app (26.1.0) and test app
  6. oracle 存储过程循环打开游标数据处理
  7. 第 9 章 数据管理 - 073 - 如何实现跨 Docker 主机存储?
  8. locate 和 find
  9. 从零开始,搭建 AI 音箱 Alexa 语音服务
  10. Fragment调用startActivityForResult导致的回调Activity无法获取正确的requestId的问题