//线程安全map:ConcurrentHashMap
private Map timerTaskMap ;//
private Timer timer ;//不能放到方法里边,new 一个启动一个线程//启动了一个新线程,这个新线程并不是守护线程,所以会一直运行
publicTimer getTimer() {returntimer;
}public voidsetTimer(Timer timer) {this.timer =timer;
}//AutoEvalTask task = new AutoEvalTask();//不能放到方法里边,
/*** 启动所有定时任务
*@paramfirstTimeStr
*@paramperiodStr 秒数
*@return
*/@RequestMapping(value="/lanchAllTimerTask")
@ResponseBodypublic MaplanchAllTimerTask() {
Map res = new HashMap();try{
Map hmget = redisUtil.hmget("seller_schedule_time_list");for (Entrymap : hmget.entrySet()) {
String key= (String) map.getKey();//username+taskName
UserScheduleTimes value = (UserScheduleTimes) map.getValue();//定时任务信息对象
if(CollectionUtils.isEmpty(timerTaskMap)) {
timerTaskMap= new ConcurrentHashMap();
}
AutoEvalTask task=timerTaskMap.get(key);if (task!=null) {
task.cancel();//从定时任务队列中移除
}if (timer==null) {
timer= new Timer();//只有一个此定时任务队列。
}
task= new AutoEvalTask();//定时任务对象//task = SpringContextHolder.getBean("autoEvalTask");//会报异常 java.lang.IllegalStateException: Task already scheduled or cancelled
task.setUserScheduleTimes(value);
timerTaskMap.put(key, task);if (value !=null) {
Date HHmmDate=value.getFirstTime();
Date executeDate=getExecuteDate(HHmmDate);
timer.schedule(task, executeDate, value.getPeriod()*1000);//如果时间在当前时间之前,立即执行。然后间隔时间再次执行。
}
LOGGER.info("key:"+key+",value:"+value);
}
res.put("status", "succ");
}catch(Exception e) {
LOGGER.info("lanchAllTimerTask方法异常!",e);
e.printStackTrace();
res.put("status", "fail");
}returnres;
}/*** 获取执行定时任务时刻,如果是当前时刻之前 第二天此时刻开始执行
*@paramHHmmDate
*@return
*/
privateDate getExecuteDate(Date HHmmDate) {
Calendar now=Calendar.getInstance();
Date executeDate= new Date(now.get(Calendar.YEAR) - 1900, now.get(Calendar.MONTH),
now.get(Calendar.DAY_OF_MONTH), HHmmDate.getHours(), HHmmDate.getMinutes(), HHmmDate.getSeconds());if (executeDate.compareTo(new Date())<0) {//不加此设置,如果是当前时刻 立即执行
executeDate = DatesUtils.getTimePeriodBeforeDate(-1, executeDate);//1天后的此时刻执行任务。(最准确是开始时间+间隔倍数 大于当前时间最近的时间)
}returnexecuteDate;
}