定时任务,客户页面操作,使用java.util.timer(要求时间精确度不高的定时任务)
Posted erlongxizhu-03
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了定时任务,客户页面操作,使用java.util.timer(要求时间精确度不高的定时任务)相关的知识,希望对你有一定的参考价值。
- 定时任务,客户页面操作,使用java.util.timer,因为@schedule 注解中定时的时间不能在不启动项目情况下修改。
- timer.cancel()任务队列全部移除,task.cancel()只移除队列中的一个任务。
- 页面操作定时任务,传递参数(访问任务接口URL和对应参数),修改timer 中Task,修改需要先移除Task.cancel()。
- 注意timer只能有一个对象,因为多个就会造成多线程定时任务(多线程需要保证每个队列timer中任务不重复)。
好了,不多说 上代码:这里数据是存的Redis。
//线程安全map:ConcurrentHashMap private Map<String, AutoEvalTask> timerTaskMap ;//<userName+taskName,timerTask> private Timer timer ;//不能放到方法里边,new 一个启动一个线程//启动了一个新线程,这个新线程并不是守护线程,所以会一直运行 public Timer getTimer() return timer; public void setTimer(Timer timer) this.timer = timer; //AutoEvalTask task = new AutoEvalTask();//不能放到方法里边, /** * 启动所有定时任务 * @param firstTimeStr * @param periodStr 秒数 * @return */ @RequestMapping(value="/lanchAllTimerTask") @ResponseBody public Map<String, String> lanchAllTimerTask() Map<String, String> res = new HashMap<String, String>(); try Map<Object, Object> hmget = redisUtil.hmget("seller_schedule_time_list"); for (Entry<Object, Object> map : hmget.entrySet()) String key = (String) map.getKey();//username+taskName UserScheduleTimes value = (UserScheduleTimes) map.getValue();//定时任务信息对象 if (CollectionUtils.isEmpty(timerTaskMap)) timerTaskMap = new ConcurrentHashMap<String, AutoEvalTask>(); 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"); return res; /** * 获取执行定时任务时刻,如果是当前时刻之前 第二天此时刻开始执行 * @param HHmmDate * @return */ private Date 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天后的此时刻执行任务。(最准确是开始时间+间隔倍数 大于当前时间最近的时间) return executeDate;
/** * 定时任务类 * @author zel * @date 2019年7月22日 下午8:44:35 * */ @Component public class AutoEvalTask extends TimerTask private static final Logger LOGGER = LoggerFactory.getLogger(AutoEvalTask.class); //@Autowired AutoEvaluateTask autoEvaluateTask = SpringContextHolder.getBean("autoEvaluateTask");//外边AutoEvalTask是new的则不会注入 private UserScheduleTimes userScheduleTimes; public UserScheduleTimes getUserScheduleTimes() return userScheduleTimes; public void setUserScheduleTimes(UserScheduleTimes userScheduleTimes) this.userScheduleTimes = userScheduleTimes; /* (non-Javadoc) * @see java.util.TimerTask#run() */ @Override public void run() try //String url = "http://192.168.1.10:30002/tradeserver/delaysendmsg.api/scheduleTask/autoEvaluateInterface"; String url = this.userScheduleTimes.getUrl(); Map<String, String> param = this.userScheduleTimes.getParam(); String userName = param.get("userName"); if (userName.indexOf(",")!=-1) String[] split = userName.split(","); for (int i = 0; i < split.length; i++) LOGGER.info(split[i] + ",多个用户测试定时任务"); //autoEvaluateTask.autoEvaluateAllFinished2(split[i], "35"); Map<String, String> paramInterfaceUrl = new HashMap<String, String>(); paramInterfaceUrl.put("userName", split[i]); String httpGetWithJSON = HttpClientUtil.httpGetWithJSON(url, paramInterfaceUrl); LOGGER.info("定时任务"+this.userScheduleTimes.getTaskName()+"结果:"+httpGetWithJSON); else //单个用户 LOGGER.info(userName + ",单个测试定时任务"); //autoEvaluateTask.autoEvaluateAllFinished2(userName, "35"); String httpGetWithJSON = HttpClientUtil.httpGetWithJSON(url, param); LOGGER.info("定时任务"+this.userScheduleTimes.getTaskName()+"结果:"+httpGetWithJSON); catch (Exception e) e.printStackTrace(); LOGGER.info("定时任务run方法异常!",e);
相关实体类entity:
/** * 客户设置的定时任务 时间点和 间隔时长, * @author zel * @date 2019年7月19日 下午12:16:51 * */ public class UserScheduleTimes implements Serializable /** * */ private static final long serialVersionUID = 8534961773338501488L; private String taskName;//定时任务名称 //url 及参数信息: private String url;//定时执行URL,并附带参数。 private Map<String, String> param;//参数,transient:不被序列化 // private String userName;//多用户逗号隔开 // private String orderTime;//订单时间 // private String type;//"manyUser":多用户 。 //任务参数 private Date firstTime;//任务开始执行时间。 private Long period;//任务间隔时长 单位/秒 public Map<String, String> getParam() return param; public void setParam(Map<String, String> param) this.param = param; public String getUrl() return url; public void setUrl(String url) this.url = url; public String getTaskName() return taskName; public void setTaskName(String taskName) this.taskName = taskName; public Date getFirstTime() return firstTime; public void setFirstTime(Date firstTime) this.firstTime = firstTime; public Long getPeriod() return period; public void setPeriod(Long period) this.period = period; @Override public String toString() return "UserScheduleTimes [taskName=" + taskName + ", url=" + url + ", param=" + param + ", firstTime=" + firstTime + ", period=" + period + "]";
以上是关于定时任务,客户页面操作,使用java.util.timer(要求时间精确度不高的定时任务)的主要内容,如果未能解决你的问题,请参考以下文章
django-vuecelery延迟任务定时任务 django中使用celery 秒杀功能 双写一致性 首页轮播图定时更新 课程前端页面