QuartzUtils工具類

  • QuartzUtils工具類,簡化Quartz須要程序員思考和編寫的代碼邏輯。

1.增長QuartzUtils工具類java

2.採用優先級的ShutDownHook進行Scheduler和Job的關閉。git

3.加入Quartz插件Plugin支持。LogPlugin和ShutdownHookPlugin.程序員

4.新增MxBean堅持Java程序和任務狀態。例如內存監控,死鎖監控。github

5.已打包依賴到github倉庫。 倉庫地址:https://github.com/huangyueranbbc/QuartzUtils-1.0.0-RELEASE安全

    pom增長配置:ide

<repositories>
        <repository>
            <id>QuartzUtils</id>
            <name>QuartzUtils</name>
            <url>https://raw.github.com/huangyueranbbc/QuartzUtils-1.0.0-RELEASE/master/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
</repositories>

<dependency>
   <groupId>com.hyr.quartz.utils</groupId>
   <artifactId>QuartzUtils</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>

Release

2019-1-14 V1.0.0

一、支持延遲定時任務。
二、簡化調用Quartz過程。一行代碼搞定。
QuartzUtils.scheduleWithFixedDelay(scheduler, MyJob.class, 0, 1, TimeUnit.SECONDS, -1, "ProducerJob", "QUARTZ-JOB-GROUP");
三、新增具備優先級的ShutdownHook進行Quartz組件的順序安全關閉。
四、新增MXBean進行任務過程監測。
五、優化Quartz Plugin插件。提供Job/Trigger日誌、ShutDownHook插件。
六、提供優化的Listener監聽器。 能夠定製修改。
七、支持日誌級別設置。
八、提供測試入口。

 

 

  • 工具類使用DEMO:

核心代碼只有一行工具

QuartzUtils.scheduleWithFixedDelay(scheduler, MyJob.class, 0, 1, TimeUnit.SECONDS, -1, "ProducerJob", "QUARTZ-JOB-GROUP");
/*******************************************************************************
 * @date 2018-11-06 下午 2:20
 * @author: <a href=mailto:huangyr>黃躍然</a>
 * @Description:
 ******************************************************************************/
public class QuartzUtilsTest {

    public static void main(String[] args) throws SchedulerException {
        StdSchedulerFactory schedulerFactory1 = QuartzUtils.getStdSchedulerFactory(2, Thread.NORM_PRIORITY, "UPLOAD_JOB1", "UPLOAD_JOB1");
        Scheduler scheduler = schedulerFactory1.getScheduler();

        StdSchedulerFactory schedulerFactory2 = QuartzUtils.getStdSchedulerFactory(2, Thread.NORM_PRIORITY, "UPLOAD_JOB2", "UPLOAD_JOB2");
        Scheduler scheduler2 = schedulerFactory2.getScheduler();

        QuartzUtils.addSchedulerShutdownHook(scheduler);
        QuartzUtils.addSchedulerShutdownHook(scheduler2);

        QuartzUtils.startLogPlugin(scheduler, QuartzUtils.LOG_INFO); // 啓動日誌插件
        QuartzUtils.startShutDownHookPlugin(scheduler); // 啓動ShutDownHook插件


        QuartzUtils.startLogPlugin(scheduler2, QuartzUtils.LOG_DEBUG); // 啓動日誌插件
        QuartzUtils.startShutDownHookPlugin(scheduler2); // 啓動ShutDownHook插件

        // 綁定單個Listener監聽器
        QuartzUtils.bindSchedulerListenerManager(scheduler, new DefaultSchedulerListener("DefaultSchedulerListener"), new DefaultJobListener("DefaultJobListener"), new DefaultTriggerListener("DefaultTriggerListener"));
        QuartzUtils.bindSchedulerListenerManager(scheduler2, new DefaultSchedulerListener("DefaultSchedulerListener"), new DefaultJobListener("DefaultJobListener"), new DefaultTriggerListener("DefaultTriggerListener"));

        // 綁定多個Listener監聽器
        List<SchedulerListener> schedulerListeners = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            schedulerListeners.add(new DefaultSchedulerListener("SchedulerListener--" + i));
        }

        List<JobListener> jobListeners = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            jobListeners.add(new DefaultJobListener("JobListener--" + i));
        }

        List<TriggerListener> triggerListeners = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            triggerListeners.add(new DefaultTriggerListener("TriggerListener--" + i));
        }
        // QuartzUtils.bindSchedulerListenerManagers(scheduler, schedulerListeners, jobListeners, triggerListeners);

        // 注入屬性Map
        JobDataMap dataMap = new JobDataMap();
        dataMap.put("jobDesc", "job desc.");

        QuartzUtils.scheduleWithFixedDelay(scheduler, MyJob.class, 0, 1, TimeUnit.SECONDS, -1, "ProducerJob", "QUARTZ-JOB-GROUP");

        // 注入屬性
        //QuartzUtils.scheduleWithFixedDelay(scheduler2, MyJob.class, 0, 2, TimeUnit.SECONDS, -1, "ProducerJobData1", "QUARTZ-JOB-GROUP", dataMap);

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //System.exit(0);
    }

}

 

  • 工具類部分代碼,詳細代碼見項目:
/*******************************************************************************
 * @date 2018-11-13 下午 5:53
 * @author: <a href=mailto:huangyr>黃躍然</a>
 * @Description: Quartz工具類
 ******************************************************************************/
public class QuartzUtils {

    private static Logger log = LoggerFactory.getLogger(QuartzUtils.class);

    private static ShutdownHookManager shutdownHookManager = ShutdownHookManager.get(); // shutdownhook

    // QuartzLoggingPlugin 日誌級別
    @SuppressWarnings("WeakerAccess")
    public final static int LOG_TRACE = 0;

    @SuppressWarnings("WeakerAccess")
    public final static int LOG_DEBUG = 10;

    @SuppressWarnings("WeakerAccess")
    public final static int LOG_INFO = 20;

    @SuppressWarnings("WeakerAccess")
    public final static int LOG_WARN = 30;

    @SuppressWarnings("WeakerAccess")
    public final static int LOG_ERROR = 40;

    /**
     * @param threadCount      線程數
     * @param threadPriority   線程優先級 5默認優先級
     * @param threadNamePrefix 工做線程池中線程名稱的前綴將被附加前綴
     * @param schedulerName    實例名稱
     * @return
     * @throws SchedulerException
     */
    public static StdSchedulerFactory getStdSchedulerFactory(int threadCount, int threadPriority, String threadNamePrefix, String schedulerName) throws SchedulerException {
        Properties props = new Properties();
        props.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        props.setProperty("org.quartz.threadPool.threadCount", String.valueOf(threadCount)); // 線程數
        props.setProperty("org.quartz.threadPool.threadPriority", String.valueOf(threadPriority)); // 線程優先級 5默認優先級
        props.setProperty("org.quartz.threadPool.threadNamePrefix", threadNamePrefix); // 工做線程池中線程名稱的前綴將被附加前綴
        props.setProperty("org.quartz.scheduler.instanceName", schedulerName); // 實例名稱
        props.setProperty("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore"); // 將job數據保存在ram,性能最高。但程序崩潰,job調度數據會丟失。
        props.setProperty("org.quartz.scheduler.skipUpdateCheck","true");
        return new StdSchedulerFactory(props);
    }

    public static StdSchedulerFactory getStdSchedulerFactory(Properties props) throws SchedulerException {
        return new StdSchedulerFactory(props);
    }

    public static StdSchedulerFactory getStdSchedulerFactory(String schedulerName) throws SchedulerException {
        Properties props = new Properties();
        props.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        props.setProperty("org.quartz.threadPool.threadCount", "1"); // 線程數
        props.setProperty("org.quartz.threadPool.threadPriority", String.valueOf(Thread.NORM_PRIORITY)); // 線程優先級 5默認優先級
        props.setProperty("org.quartz.threadPool.threadNamePrefix", schedulerName); // 工做線程池中線程名稱的前綴將被附加前綴
        props.setProperty("org.quartz.scheduler.instanceName", schedulerName); // 實例名稱
        props.setProperty("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore"); // 將job數據保存在ram,性能最高。但程序崩潰,job調度數據會丟失。
        props.setProperty("org.quartz.scheduler.skipUpdateCheck","true");
        return new StdSchedulerFactory(props);
    }

    /**
     * 綁定監聽器
     *
     * @param scheduler
     * @param schedulerListener
     * @param jobListener
     * @param triggerListener
     * @throws SchedulerException
     */
    public static void bindSchedulerListenerManager(Scheduler scheduler, SchedulerListener schedulerListener, JobListener jobListener, TriggerListener triggerListener) throws SchedulerException {
        ListenerManager listenerManager = scheduler.getListenerManager();
        if (schedulerListener != null) {
            listenerManager.addSchedulerListener(schedulerListener);
        }
        if (jobListener != null) {
            listenerManager.addJobListener(jobListener);
        }
        if (triggerListener != null) {
            listenerManager.addTriggerListener(triggerListener);
        }
    }

    /**
     * 綁定多個監聽器
     *
     * @param scheduler
     * @param schedulerListeners
     * @param jobListeners
     * @param triggerListeners
     * @throws SchedulerException
     */
    public static void bindSchedulerListenerManagers(Scheduler scheduler, Collection<SchedulerListener> schedulerListeners, Collection<JobListener> jobListeners, Collection<TriggerListener> triggerListeners) throws SchedulerException {
        ListenerManager listenerManager = scheduler.getListenerManager();
        if (schedulerListeners != null && !schedulerListeners.isEmpty()) {
            for (SchedulerListener schedulerListener : schedulerListeners) {
                listenerManager.addSchedulerListener(schedulerListener);
            }
        }
        if (jobListeners != null && !jobListeners.isEmpty()) {
            for (JobListener jobListener : jobListeners) {
                listenerManager.addJobListener(jobListener);
            }
        }
        if (triggerListeners != null && !triggerListeners.isEmpty()) {
            for (TriggerListener triggerListener : triggerListeners) {
                listenerManager.addTriggerListener(triggerListener);
            }
        }
    }

    /**
     * 延時啓動
     *
     * @param scheduler    調度器
     * @param job          JobClass
     * @param initialDelay 首次延時啓動時間
     * @param timeUnit     時間單位
     * @param timer        cron表達式
     * @param jobName      任務名稱
     * @param groupName    組名
     */
    public static void scheduleWithFixedDelayByCron(Scheduler scheduler, Class<? extends Job> job, long initialDelay, TimeUnit timeUnit, String timer, String jobName, String groupName) {
        try {
            long delayMillis = timeUnit.toMillis(initialDelay); // 延時啓動時間
            JobDetail jobDetail = getJobDetail(job, jobName, groupName);
            long tmpTime = System.currentTimeMillis() + delayMillis; //延遲啓動任務時間
            Date statTime = new Date(tmpTime); // 啓動時間

            Trigger trigger = getTrigger(timer, jobName, groupName, statTime);

            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
            log.info("job:{} is start. timer:{}", jobName, timer);
        } catch (Exception e) {
            log.error("add job error. jobName:{}, timer:{}", jobName, timer, e);
        }
    }

    /**
     * 延時啓動
     *
     * @param scheduler    調度器
     * @param job          JobClass
     * @param initialDelay 首次延時啓動時間
     * @param timeUnit     時間單位
     * @param timer        cron表達式
     * @param jobName      任務名稱
     * @param groupName    組名
     * @param dataMap      屬性注入 以JavaBean的形式注入,須要該屬性名和set方法
     */
    public static void scheduleWithFixedDelayByCron(Scheduler scheduler, Class<? extends Job> job, long initialDelay, TimeUnit timeUnit, String timer, String jobName, String groupName, JobDataMap dataMap) {
        try {
            long delayMillis = timeUnit.toMillis(initialDelay); // 延時啓動時間
            JobDetail jobDetail = getJobDetailBindData(job, jobName, groupName, dataMap);
            long tmpTime = System.currentTimeMillis() + delayMillis; //延遲啓動任務時間
            Date statTime = new Date(tmpTime); // 啓動時間

            Trigger trigger = getTrigger(timer, jobName, groupName, statTime);

            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
            log.info("job:{} is start. timer:{}", jobName, timer);
        } catch (Exception e) {
            log.error("add job error. jobName:{}, timer:{}", jobName, timer, e);
        }
    }

    /**
     * @param scheduler    調度器
     * @param job          JobClass
     * @param initialDelay 首次延時啓動時間
     * @param timeUnit     時間單位
     * @param delay        間隔時間
     * @param repeatCount  重複執行次數 -1無限次數 0不執行
     * @param jobName      任務名稱
     * @param groupName    組名
     */
    public static void scheduleWithFixedDelay(Scheduler scheduler, Class<? extends Job> job, long initialDelay, long delay, TimeUnit timeUnit, int repeatCount, String jobName, String groupName) {
        long intervalTime = timeUnit.toMillis(delay);
        try {
            addJobShutdownHook(scheduler, jobName, groupName);
            long delayMillis = timeUnit.toMillis(initialDelay); // 延時啓動時間
            JobDetail jobDetail = getJobDetail(job, jobName, groupName);
            long tmpTime = System.currentTimeMillis() + delayMillis; //延遲啓動任務時間
            Date statTime = new Date(tmpTime); // 啓動時間

            Trigger trigger = getSimpleTrigger(intervalTime, jobName, groupName, repeatCount, statTime);

            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
            log.info("job:{} is start. delay:{}", jobName, delay);
        } catch (Exception e) {
            log.error("add job error. jobName:{}, intervalTime:{}", jobName, intervalTime, e);
        }
    }

    /**
     * @param scheduler    調度器
     * @param job          JobClass
     * @param initialDelay 首次延時啓動時間
     * @param timeUnit     時間單位
     * @param delay        間隔時間
     * @param repeatCount  重複執行次數 -1無限次數 0不執行
     * @param jobName      任務名稱
     * @param groupName    組名
     * @param dataMap      屬性注入 以JavaBean的形式注入,須要該屬性名和set方法
     */
    public static void scheduleWithFixedDelay(Scheduler scheduler, Class<? extends Job> job, long initialDelay, long delay, TimeUnit timeUnit, int repeatCount, String jobName, String groupName, JobDataMap dataMap) {
        long intervalTime = timeUnit.toMillis(delay);
        try {
            addJobShutdownHook(scheduler, jobName, groupName);
            long delayMillis = timeUnit.toMillis(initialDelay); // 延時啓動時間
            JobDetail jobDetail = getJobDetailBindData(job, jobName, groupName, dataMap);
            long tmpTime = System.currentTimeMillis() + delayMillis; //延遲啓動任務時間
            Date statTime = new Date(tmpTime); // 啓動時間

            Trigger trigger = getSimpleTrigger(intervalTime, jobName, groupName, repeatCount, statTime);

            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
            log.info("job:{} is start. delay:{}", jobName, delay);
        } catch (Exception e) {
            log.error("add job error. jobName:{}, intervalTime:{}", jobName, intervalTime, e);
        }
    }

    private static Trigger getSimpleTrigger(long delay, String jobName, String groupName, int repeatCount, Date statTime) {
        SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
        simpleScheduleBuilder.withIntervalInMilliseconds(delay).withRepeatCount(repeatCount);
        simpleScheduleBuilder.withMisfireHandlingInstructionFireNow(); // 以當前時間爲觸發頻率當即觸發執行

        return TriggerBuilder.newTrigger()
                .withPriority(Trigger.DEFAULT_PRIORITY) // 優先級
                .withIdentity("Trigger-" + jobName, "Trigger-" + groupName)
                .startAt(statTime)  //默認當前時間啓動
                .withSchedule(simpleScheduleBuilder) //兩秒執行一次
                .build();
    }

    /**
     * 給trigger下全部job注入屬性
     *
     * @param delay       間隔時間
     * @param repeatCount 重複執行次數 -1無限次數 0不執行
     * @param jobName     任務名稱
     * @param groupName   組名
     * @param statTime    開始執行時間
     * @param dataMap     屬性注入 以JavaBean的形式注入,須要該屬性名和set方法
     * @return
     */
    private static Trigger getSimpleTriggerBindData(long delay, String jobName, String groupName, int repeatCount, Date statTime, JobDataMap dataMap) {
        SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule();
        simpleScheduleBuilder.withIntervalInMilliseconds(delay).withRepeatCount(repeatCount);
        simpleScheduleBuilder.withMisfireHandlingInstructionFireNow(); // 以當前時間爲觸發頻率當即觸發執行

        return TriggerBuilder.newTrigger()
                .withPriority(Trigger.DEFAULT_PRIORITY) // 優先級
                .withIdentity("Trigger-" + jobName, "Trigger-" + groupName)
                .startAt(statTime)  //默認當前時間啓動
                .withSchedule(simpleScheduleBuilder) //兩秒執行一次
                .usingJobData(dataMap) // 輸入屬性
                .build();
    }

    private static Trigger getTrigger(String timer, String jobName, String groupName, Date statTime) {
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(timer);
        cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed(); // 默認 以當前時間爲觸發頻率馬上觸發一次執行,而後按照Cron頻率依次執行.會合並部分的misfire,正常執行下一個週期的任務.
        // cronScheduleBuilder.withMisfireHandlingInstructionDoNothing(); // 全部的misfire無論,執行下一個週期的任務)
        // cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); //全部misfire的任務會立刻執行

        return TriggerBuilder.newTrigger()
                .withPriority(Trigger.DEFAULT_PRIORITY) // 優先級
                .withIdentity("Trigger-" + jobName, "Trigger-" + groupName)
                .startAt(statTime)  //默認當前時間啓動
                .withSchedule(cronScheduleBuilder) //兩秒執行一次
                .build();
    }

    /**
     * 給trigger下全部的Job注入屬性
     *
     * @param timer     cron表達式
     * @param jobName   任務名稱
     * @param groupName 組名
     * @param statTime  開始執行時間
     * @param dataMap   屬性注入 以JavaBean的形式注入,須要該屬性名和set方法
     * @return
     */
    private static Trigger getTriggerBindData(String timer, String jobName, String groupName, Date statTime, JobDataMap dataMap) {
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(timer);
        cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed(); // 默認 以當前時間爲觸發頻率馬上觸發一次執行,而後按照Cron頻率依次執行.會合並部分的misfire,正常執行下一個週期的任務.
        // cronScheduleBuilder.withMisfireHandlingInstructionDoNothing(); // 全部的misfire無論,執行下一個週期的任務)
        // cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); //全部misfire的任務會立刻執行

        return TriggerBuilder.newTrigger()
                .withPriority(Trigger.DEFAULT_PRIORITY) // 優先級
                .withIdentity("Trigger-" + jobName, "Trigger-" + groupName)
                .startAt(statTime)  //默認當前時間啓動
                .withSchedule(cronScheduleBuilder) //兩秒執行一次
                .usingJobData(dataMap) // 注入屬性
                .build();
    }

    private static JobDetail getJobDetail(Class<? extends Job> job, String jobName, String groupName) {
        return JobBuilder.newJob(job)
                .storeDurably(true) // 若是一個job是非持久的,當沒有活躍的trigger與之關聯的時候,會被自動地從scheduler中刪除
                .requestRecovery(true) // job可恢復。scheduler發生硬關閉(hard shutdown)(好比運行的進程崩潰了,或者關機了),則當scheduler從新啓動的時候,該job會被從新執行。
                .withIdentity(jobName, groupName) //job 的name和group
                .build();
    }

    /**
     * @param job       任務對象
     * @param jobName   任務名稱
     * @param groupName 組名
     * @param dataMap   屬性注入 以JavaBean的形式注入,須要該屬性名和set方法
     * @return
     */
    private static JobDetail getJobDetailBindData(Class<? extends Job> job, String jobName, String groupName, JobDataMap dataMap) {
        return JobBuilder.newJob(job)
                .storeDurably(true) // 若是一個job是非持久的,當沒有活躍的trigger與之關聯的時候,會被自動地從scheduler中刪除
                .requestRecovery(true) // job可恢復。scheduler發生硬關閉(hard shutdown)(好比運行的進程崩潰了,或者關機了),則當scheduler從新啓動的時候,該job會被從新執行。
                .withIdentity(jobName, groupName) //job 的name和group
                .usingJobData(dataMap) // 屬性注入
                .build();
    }

    /**
     * 刪除定時Job
     *
     * @param scheduler
     * @param jobName
     * @param groupName
     * @throws SchedulerException
     */
    public static void removeJob(Scheduler scheduler, String jobName, String groupName) throws SchedulerException {
        scheduler.deleteJob(JobKey.jobKey(jobName, groupName));
    }

    /**
     * 啓動日誌插件
     *
     * @param scheduler
     * @param log_level 日誌統一打印級別
     */
    public static void startLogPlugin(Scheduler scheduler, int log_level) {
        try {
            String schedulerName = scheduler.getSchedulerName();
            // trigger log plugin
            QuartzLoggingTriggerHistoryPlugin triggerLogPlugin = new QuartzLoggingTriggerHistoryPlugin();
            triggerLogPlugin.initialize(schedulerName, scheduler, new SimpleClassLoadHelper());
            triggerLogPlugin.setLog_level(log_level);
            // job log plugin
            QuartzLoggingJobHistoryPlugin jobLogPlugin = new QuartzLoggingJobHistoryPlugin();
            jobLogPlugin.initialize(schedulerName, scheduler, new SimpleClassLoadHelper());
            jobLogPlugin.setLog_level(log_level);

            addPluginShutdownHook(triggerLogPlugin);
            addPluginShutdownHook(jobLogPlugin);

            triggerLogPlugin.start();
            jobLogPlugin.start();
        } catch (SchedulerException e) {
            log.error("start log plugin error.", e);
        }
    }

    /**
     * 啓動ShutDownHook插件
     *
     * @param scheduler
     */
    public static void startShutDownHookPlugin(Scheduler scheduler) {
        try {
            String schedulerName = scheduler.getSchedulerName();
            QuartzShutdownHookPlugin shutdownHookPlugin = new QuartzShutdownHookPlugin();
            shutdownHookPlugin.initialize(schedulerName, scheduler, new SimpleClassLoadHelper());
            addPluginShutdownHook(shutdownHookPlugin);
            shutdownHookPlugin.start();
        } catch (Exception e) {
            log.error("start shutdown hook plugin error.", e);
        }
    }

    /**
     * plugin shutdownhook
     *
     * @param schedulerPlugin
     */
    public static void addPluginShutdownHook(final SchedulerPlugin schedulerPlugin) {
        Thread schedulerShutdownHook = new Thread() {
            @Override
            public void run() {
                if (schedulerPlugin != null) {
                    synchronized (schedulerPlugin) {
                        schedulerPlugin.shutdown();
                        log.info("scheduler plugin:{} shutdown success.", schedulerPlugin.getClass().getSimpleName());
                    }
                }
            }
        };
        shutdownHookManager.addShutdownHook(schedulerShutdownHook, HookPriority.PLUGIN_PRIORITY.value());
    }

    /**
     * Job ShutdownHook
     *
     * @param scheduler
     * @param jobName
     * @param groupName
     */
    public static void addJobShutdownHook(final Scheduler scheduler, final String jobName, final String groupName) {
        Thread quartzJobShutdownHook = new Thread() {
            @Override
            public void run() {
                try {
                    if (scheduler != null) {
                        synchronized (scheduler) {
                            if (!scheduler.isShutdown()) {
                                removeJob(scheduler, jobName, groupName);
                            }
                            log.info("job:{} remove success.", jobName);
                        }
                    }
                } catch (Exception e) {
                    log.error("delete job error. jobName:{}, groupName:{}", jobName, groupName, e);
                }
            }
        };
        // 注:該優先級要比Schedule的Hook優先級高
        shutdownHookManager.addShutdownHook(quartzJobShutdownHook, HookPriority.JOB_PRIORITY.value());
    }

    /**
     * Scheduler ShutdownHook
     * 避免和Quartz自帶ShutdownPlugin插件同時使用
     *
     * @param scheduler
     */
    public static void addSchedulerShutdownHook(final Scheduler scheduler) {
        Thread schedulerShutdownHook = new Thread() {
            @Override
            public void run() {
                try {
                    if (scheduler != null) {
                        synchronized (scheduler) {
                            String schedulerName = scheduler.getSchedulerName();
                            if (!scheduler.isShutdown()) {
                                scheduler.shutdown(true);
                            }
                            log.info("scheduler shutdown success. scheduler:{}", schedulerName);
                        }
                    }
                } catch (Exception e) {
                    log.error("shutdown scheduler error.", e);
                }
            }
        };
        // 注:該優先級要比Job的Hook優先級低
        shutdownHookManager.addShutdownHook(schedulerShutdownHook, HookPriority.SCHEDULER_PRIORITY.value());
    }

}

 

項目地址:https://github.com/huangyueranbbc/QuartzUtils性能

相關文章
相關標籤/搜索