通常的系統都會有一些定時任務,那麼咱們將這個定時任務封裝起來,只要系統須要添加定時任務時,只需調用此方法傳入所須要的值便可完成定時任務。 本身自學整理的一些隨筆java
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.對同步方式進行封裝app
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.設置須要定時同步的週期對象ide
(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)定時任務的對象設定,並指定任務名 任務組名ui
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.封裝調度機信息,用於存儲所須要的同步週期方式this
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.封裝方法生成設定的所指望的同步規則spa
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.設置定時任務(定時時間所要執行的任務)code
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())); } }