定时任务,客户页面操作,使用java.util.timer(要求时间精确度不高的定时任务)

Posted erlongxizhu-03

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了定时任务,客户页面操作,使用java.util.timer(要求时间精确度不高的定时任务)相关的知识,希望对你有一定的参考价值。

  1. 定时任务,客户页面操作,使用java.util.timer,因为@schedule 注解中定时的时间不能在不启动项目情况下修改。
  2. timer.cancel()任务队列全部移除,task.cancel()只移除队列中的一个任务。
  3. 页面操作定时任务,传递参数(访问任务接口URL和对应参数),修改timer 中Task,修改需要先移除Task.cancel()。
  4. 注意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(要求时间精确度不高的定时任务)的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot中使用@Scheduled创建定时任务

怎样删除mysql的job定时器

不需要任何插件支持运行网页定时任务实现方法

Linux定时任务管理

django-vuecelery延迟任务定时任务 django中使用celery 秒杀功能 双写一致性 首页轮播图定时更新 课程前端页面

如何用参数传给Spring定时任务,以致可任意调整定时时间