人生何處不春風 2021-12-31 11:03 采纳率: 33.3%
浏览 71

Quartz创建定时任务时,每次创建或修改定时任务的时间都新建一个StdSchedulerFactory获取Scheduler,请问这样合理吗?会造成定时任务不执行的情况吗

现象
系统通过配置添加或修改定时任务,每次添加或修改执行时间的时候都会调用下面代码块中的addJob方法,以致每次都创建StdSchedulerFactory对象;总会出现定时任务不执行的问题,是否和这种机制有关?

public static Scheduler getScheduler() throws SchedulerException {
        Properties props = new Properties();
        props.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,"org.quartz.simpl.SimpleThreadPool");
        props.put("org.quartz.threadPool.threadCount", "90");
        sf = new StdSchedulerFactory(props);
        return sf.getScheduler();
    }


    /**
     *  添加一个定时任务
     *
     * @param jobId 任务名
     * @param job     任务
     * @param cronExpression    trigger设置表达式
     * @param jobDataMap       job的参数
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void addJob(String jobId, Job job, String cronExpression, String methodName, List<String[]> logInfoList) 
            throws ParseException, SchedulerException {
        String jobName = generateJobName(jobId);
        Scheduler scheduler = getScheduler();
        //新增job
        JobDetail jobDetail = JobBuilder
                .newJob(job.getClass())
                .withIdentity(jobName, JOB_GROUP_NAME)
                .storeDurably()
                .build();    //任务名,任务组,任务执行类

        scheduler.addJob(jobDetail,true);
        System.out.println("-------------------------------------------------------------------------------scheduler.addJob(jobDetail,true); 执行完毕");
        logger.info("新增定时任务"+jobName);
        //新增触发器
        String[] cronExps = StringUtils.splitByWholeSeparator(cronExpression,SEPARATOR);
        for(int i=0;i<cronExps.length;i++){
            try{
                String triggerId = TRIGGER_NAME+jobId+"_"+generateSystime();
                CronTrigger trigger = TriggerBuilder
                        .newTrigger()
                        .withIdentity(triggerId, TRIGGER_GROUP_NAME).forJob(jobName, JOB_GROUP_NAME)
                        .withSchedule(CronScheduleBuilder.cronSchedule(cronExps[i]).withMisfireHandlingInstructionFireAndProceed())
                        .build();
                if(logInfoList != null) {
                    logInfoList.add(new String[]{triggerId, jobName, cronExpression, methodName});
                }else {
                    LoggerUtils.quartzInitLoggerJob(triggerId, jobName, cronExpression, methodName);
                }
                scheduler.scheduleJob(trigger);
                if(!scheduler.isShutdown()) {
                    scheduler.start();
                    System.out.println("-------------------------------------------------------------------------------scheduler.start(); 执行完毕");
                }
                logger.info("新增定时任务触发器"+trigger.getKey().getName());
            }catch (SchedulerException ex){
                logger.info(ex.getMessage());
                System.out.println(ex.getMessage());
                continue;
            }
        }
    }
  • 通过测试发现,系统刚刚启动时,定时任务是按时执行的,但是随着系统启动时间变长,定时任务就出现延迟执行或不执行的情况,把org.quartz.threadPool.threadCount的数值变大,出现这种情况的时间就推迟;
  • 想知道这种代码机制是不是有问题?怎样能保证定时任务肯定会执行且会按时执行?
  • 写回答

1条回答 默认 最新

  • 关注

    工厂类可以定义为静态变量,每次使用前检查一下,没有就创建,有就使用。但现在一般都是通过注解或者配置实现了,参考:

    
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-2.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
        
        <!-- 更新考试状态 -->
        <bean id="GetLievCourseStateScheduleExecute" class="com.schedule.GetLievCourseStateScheduleExecute" >
            <property name="baseDAO" ref="baseDAO"></property>
        </bean>
        <!--更新考试状态 -->
        <bean id="getLiveCourseStateScheduleExecute-methodInvokingJobDetail"
            class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
            <property name="name" value="GetLievCourseStateScheduleExecute_Name"></property>
            <property name="targetObject"><ref bean="GetLievCourseStateScheduleExecute"/></property>
            <property name="targetMethod"><value>execute</value></property>
            <property name="concurrent" value="false" />
        </bean>
        <!-- 更新考试状态 -->
        <bean id="courseStateScheduleExecute-cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
            <property name="jobDetail">
                <ref bean="getLiveCourseStateScheduleExecute-methodInvokingJobDetail"/>
            </property>
            <property name="cronExpression">
                <!-- 更新考试状态,每5分钟触发一次 -->
                <value>0 0/5 * * * ?</value>
            </property>
        </bean>
        
        <bean id="stdScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <!-- 更新考试状态,每5分钟触发一次 -->
                    <ref bean="courseStateScheduleExecute-cronTrigger"/> 
                </list>
            </property>
        </bean>
    </beans>
    
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 12月31日

悬赏问题

  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端