java 定时器

昨天看定时器,被Quartz定时器框架困扰到现在,以为是调用的时候出了问题,以为是我不知道怎么调用然后出的问题,结果是少了jar包。哎,这个问题真的是,告诉我们以后导入一个框架的jar包时,一定要导全,不要只导核心包,因为核心包可能依赖其他包。

定时任务不执行原因:没有导入除quartz-2.3.0-SHAPSHOT.jar以外的包。

解决方法,把其余包都导入。

这个问题真的是!!!!!真是个值得记忆的教训。现在来说说定时器吧!

我在理解定时器的时候,提出了这些问题!

首先,jdk自带Timer,TimerTask类,可以实现定时任务,为什么还需要其他定时器框架呢?

用java自带的类来做定时任务时,只需写一个类,让这个类extendsTimerTask,然后重写它的Run()方法。

然后,如果把定时器放在监听器里的话,直接在监听器的某个方法中执行Timer的schedule(task,...)方法。

我们可以发现,

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包要完整哦!其实定时器还是挺简单的对不对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值