java 定時器

昨天看定時器,被Quartz定時器框架困擾到如今,覺得是調用的時候出了問題,覺得是我不知道怎麼調用而後出的問題,結果是少了jar包。哎,這個問題真的是,告訴咱們之後導入一個框架的jar包時,必定要導全,不要只導核心包,由於核心包可能依賴其餘包。java

定時任務不執行緣由:沒有導入除quartz-2.3.0-SHAPSHOT.jar之外的包。web

解決方法,把其他包都導入。框架

這個問題真的是!!!!!真是個值得記憶的教訓。如今來講說定時器吧!ide

我在理解定時器的時候,提出了這些問題!ui

首先,jdk自帶Timer,TimerTask類,能夠實現定時任務,爲何還須要其餘定時器框架呢?spa

用java自帶的類來作定時任務時,只需寫一個類,讓這個類extendsTimerTask,而後重寫它的Run()方法。code

而後,若是把定時器放在監聽器裏的話,直接在監聽器的某個方法中執行Timer的schedule(task,...)方法。orm

咱們能夠發現,xml

schedule(task, 0, PERIOD*PERIODTIME);方法實現的定時種類很少。它不能控制一些複雜的定時任務。

因此這就是爲何要使用其餘定時器框架的緣由吧,由於不能知足複雜的任務需求。對象

那常見的定時器框架有哪些呢?

java定時器,Spring定時器,Quartz定時器。

我暫時只用過java自帶的定時器和Quartz定時器,由於Quartz定時器已經夠強大了,我以爲了解Spring定時器也就不必了。

那Quartz定時器框架是怎麼用的呢?

首先咱們要理解Quartz的幾個核心概念。

而後咱們要引入咱們須要的jar包,注意一個都不能少,否則會引起一系列問題,前面已經截圖過。

最後咱們進入代碼部分。

咱們要先建一個job類,它是任務的核心,即這個定時任務究竟要作什麼,就是作的內容。這個類須要implements該框架的Job類,而後實現它的execute()方法,方法的具體內容就是執行的這個任務,即任務的內容。

 而後,咱們須要建立一個JobDetail。

JobDetail 表示一個具體的可執行的調度程序,Job 是這個可執行程調度程序所要執行的內容,另外 JobDetail 還包含了這個任務調度的方案和策略。最開始建立的job類就會在建立它時被用到。

接着呢,咱們須要建立一個觸發器,Trigger

Trigger 表明一個調度參數的配置,何時去調。它能夠配置定時任務中的定時。尤爲是cron表達式的配置,讓定時任務想怎麼定時就怎麼定時,配置能夠在http://cron.qqe2.com/中生成,方便快捷。

最後呢,咱們須要一個調度器,Scheduler。

Scheduler 表明一個調度容器,一個調度容器中能夠註冊多個 JobDetail 和 Trigger。當 Trigger 與 JobDetail 組合,就能夠被 Scheduler 容器調度了。剛剛建立的JobDetail和Trigger都需被它調度。

最後的最後,咱們只需在監聽器或者其餘地方直接調用剛剛寫好的方法便可,而後若是實在監聽器裏調用的話,程序一執行,定時任務就開始了。下面我粘一下個人代碼。

web.xml中的配置。

<listener>
        <listener-class>com.practice.mylistener.QuartzListener</listener-class>
    </listener>

QuartzListener類。

package com.practice.mylistener;

import com.practice.tool.QuartzTimeManager;
import com.practice.tool.QuertzTask;
import com.practice.tool.job;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class QuartzListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("quertztask監聽器啓動==============================");
        QuartzTimeManager.addJob("myJob","group1","mytrigger","group1", job.class,"1-2 * * * * ?");
        System.out.println("task excute==================================");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

QuartzListener類

package com.practice.tool;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Collection;

public class QuartzTimeManager {
    private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();

    /**
     * @Description: 添加一個定時任務
     *
     * @param jobName 任務名
     * @param jobGroupName  任務組名
     * @param triggerName 觸發器名
     * @param triggerGroupName 觸發器組名
     * @param jobClass  任務
     * @param cron   時間設置,參考quartz說明文檔
     */
    public static void addJob(String jobName, String jobGroupName,
                              String triggerName, String triggerGroupName, Class jobClass, String cron) {

        try {
            Scheduler sched = schedulerFactory.getScheduler();

            // 任務名,任務組,任務執行類
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();

            // 觸發器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();

            // 觸發器名,觸發器組
            triggerBuilder.withIdentity(triggerName, triggerGroupName);
            triggerBuilder.startNow();


            // 觸發器時間設定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));


            // 建立Trigger對象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();


            // 調度容器設置JobDetail和Trigger
            sched.scheduleJob(jobDetail, trigger);


            // 啓動
            if (!sched.isShutdown()) {
                System.out.println("=================定quartz定時任務開始");
                sched.start();
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }



    /**
     * @Description: 修改一個任務的觸發時間
     *
     * @param jobName
     * @param jobGroupName
     * @param triggerName 觸發器名
     * @param triggerGroupName 觸發器組名
     * @param cron   時間設置,參考quartz說明文檔
     */
    public static void modifyJobTime(String jobName,
                                     String jobGroupName, String triggerName, String triggerGroupName, String cron) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }


            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(cron)) {
                /** 方式一 :調用 rescheduleJob 開始 */
                // 觸發器
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 觸發器名,觸發器組
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // 觸發器時間設定
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 建立Trigger對象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 :修改一個任務的觸發時間
                sched.rescheduleJob(triggerKey, trigger);
                /** 方式一 :調用 rescheduleJob 結束 */


                /** 方式二:先刪除,而後在建立一個新的Job  */
                //JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
                //Class<? extends Job> jobClass = jobDetail.getJobClass();
                //removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
                //addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
                /** 方式二 :先刪除,而後在建立一個新的Job */
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @Description: 移除一個任務
     *
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     */
    public static void removeJob(String jobName, String jobGroupName,
                                 String triggerName, String triggerGroupName) {
        try {
            Scheduler sched = schedulerFactory.getScheduler();


            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);


            sched.pauseTrigger(triggerKey);// 中止觸發器
            sched.unscheduleJob(triggerKey);// 移除觸發器
            sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 刪除任務
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @Description:啓動全部定時任務
     */
    public static void startJobs() {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            sched.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * @Description:關閉全部定時任務
     */
    public static void shutdownJobs() {
        try {
            Scheduler sched = schedulerFactory.getScheduler();
            if (!sched.isShutdown()) {
                sched.shutdown();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

job類

package com.practice.tool;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class job implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext)
            throws JobExecutionException {
        System.out.println("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
        Date date=new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Time:"+sf.format(date));
        System.out.println("Hello");
    }
}

運行結果:

最重要的一點,注意導入jar包要完整哦!其實定時器仍是挺簡單的對不對。