首页 > 技术文章 > 动态设置定时任务-线程实现

blackCatFish 2020-06-16 14:21 原文

这个需求是之前所需要的任务,当时想着使用框架来实现动态定时的,后来想想如果不用框架来实现是否应该可以;

尝试着实现没想到真的可以哈哈哈,现在就来记录一下吧因为是很久之前的 这里就没有参考链接了,q_q

先说下逻辑,业务需求是要能够动态定时,可以支持单次的定时,也要支持连续定时任务;

先上下代码:

 public R addTimer(@RequestBody WeeklyReportSetting weeklyReportSetting, HttpServletRequest request) {
        WeeklyReportSettingExample example = new WeeklyReportSettingExample();
        List<WeeklyReportSetting> weeklyReportSettingList = weeklyReportSettingMapper.selectByExample(example);
        if (isNotEmpty(weeklyReportSettingList)) {
            weeklyReportSetting.setSettingId(System.currentTimeMillis() + "");
            Date date = new Date();
            weeklyReportSetting.setSettingTime(date);
            weeklyReportSetting.setEmployeeName(SessionUtil.getUser(request).getName());
            weeklyReportSetting.setEmailTemplate(null);
            weeklyReportSettingMapper.deleteByPrimaryKey(weeklyReportSettingList.get(0).getSettingId());
            weeklyReportSettingMapper.insert(weeklyReportSetting);
        } else {
            weeklyReportSetting.setSettingId(System.currentTimeMillis() + "");
            Date date = new Date();
            weeklyReportSetting.setSettingTime(date);
            weeklyReportSetting.setEmailTemplate(null);
            weeklyReportSetting.setEmployeeName(SessionUtil.getUser(request).getName());
            weeklyReportSettingMapper.insert(weeklyReportSetting);
        }

        if (future != null) {
            future.cancel(true);
        }
        //8 8 5 ? ? 2
        //连续定时
        if (weeklyReportSetting.getReportType() == 1) {
            String corn = "";
            switch (weeklyReportSetting.getSendWeek()) {
                case 1:
                    corn = "06 00 " + weeklyReportSetting.getSendTie() + " * * SUN";
                    break;
                case 2:
                    corn = "06 00 " + weeklyReportSetting.getSendTie() + " * * MON";
                    break;
                case 3:
                    corn = "06 00 " + weeklyReportSetting.getSendTie() + " * * TUES";
                    break;
                case 4:
                    corn = "06 00 " + weeklyReportSetting.getSendTie() + " * * WED";
                    break;
                case 5:
                    corn = "06 00 " + weeklyReportSetting.getSendTie() + " * * THUR";
                    break;
                case 6:
                    corn = "06 00 " + weeklyReportSetting.getSendTie() + " * * FRI";
                    break;
                case 7:
                    corn = "06 00 " + weeklyReportSetting.getSendTie() + " * * SAT";
                    break;
            }
            //开启定时任务线程
            future = threadPoolTaskScheduler.schedule(new MyRunnable(weeklyReportSetting), new CronTrigger(corn));
        } else if (weeklyReportSetting.getReportType() == 2) {
            String time = weeklyReportSetting.getTimes();
            String[] times = time.split("-");
            String cron = "06 " + times[4] + " " + times[3] + " " + times[2] + " " + times[1] + " *";
            future = threadPoolTaskScheduler.schedule(new MyRunnable(weeklyReportSetting), new CronTrigger(cron));
        }
        return R.ok();
    }

    private class MyRunnable implements Runnable {
        private WeeklyReportSetting weeklyReportSetting;

        public MyRunnable(WeeklyReportSetting weeklyReportSetting) {
            this.weeklyReportSetting = weeklyReportSetting;
        }

        @Override
        public void run() {
//具体的逻辑代码
            }

        }
    }

代码前半部分都是业务相关代码可以忽略

 if (future != null) {
            future.cancel(true);
        }
从这开始 首先判断线程中有没有过 要是有先取消之前设置定时任务,之后记录新的
weeklyReportSetting.getSendTie()格式是两位的字符串,case部分就是匹配用户输入的星期几 某个时间点启动任务;这个属于连续定时
else 里面代码是单次定时,某天的某时的任务启动时间设置完成以后
threadPoolTaskScheduler.schedule(new MyRunnable(weeklyReportSetting), new CronTrigger(cron));
将设置信息放到线程中择时启动任务;

推荐阅读