美文网首页Spring
Java定时任务调度工具详解

Java定时任务调度工具详解

作者: 小螺丝钉cici | 来源:发表于2018-10-17 16:10 被阅读72次

    本篇内容:
    什么是定时任务调度?
    Java定时任务调度工具详解之 Timer篇
    Java定时任务调度工具详解之 Quartz篇

    定时任务调度:基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行任务。

    Java中定时调度工具:Timer 和 Quartz的区别

    1.来源:
    Timer由JDK自带,不需要引入多余的jar支持。Quartz需要引入jar包。
    2.能力:Quartz时间控制更强大,完善。
    3.Timer只有一个后台线程执行任务,Quartz拥有后台执行线程池能够使用多个线程执行任务.
    能用 Timer 处理的时候,尽量用 Timer 处理。因为 Quartz 需要的资源更多(写法也不一样)。

    ps:Quartz功能比Timer更牛逼,能用Timer就别让Quartz登场, 因为出场费很贵的。

    Java定时任务调度工具详解之Timer篇

    Timer的定义:有且仅有一个后台线程对多个业务线程进行定时定频率的调度
    Timer主要构件:Timer定时器 TimerTask定时任务
    通过 timer.schedule(myTimerTask, 2000L, 1000L) ,来定时调度

    image.png

    Timer的定时调度函数

    image.png

    Schedule 和 ScheduleAtFixedRate 区别:
    Schedule,ScheduleAtFixedRate具有同步并发性。
    1.schedule不具有并发性。下一次执行时间是相对于上一次任务结束的时间点。因此存在时间延后,不存在并发性。
    2.scheduleAtFixedRate同步并发性。下一次执行时间是相对于上一次执行任务的开始时间点。为了赶上进度。因此执行时间一般不会延误,因此存在并发性。

    timer的schedule和scheduleAtFixedRate方法一般情况下是没什么区别的,只在某个情      
    况出现时会有区别--当前任务没有来得及完成下次任务又交到手上。
    
    定时任务的执行周期是2s一次,但任务执行需要3s。
    此时,schedule 会在第一次任务执行之后,也就是3s之后执行任务。
    但是,scheduleAtFixedRate会在第一次执行的2s之后,第二次执行定时任务。
    

    我们来举个例子:
    暑假到了老师给schedule和scheduleAtFixedRate两个同学布置作业。
    老师要求学生暑假每天写2页,30天后完成作业。
    这两个学生每天按时完成作业,直到第10天,出了意外,两个学生出去旅游花了5天时间,这5天时间里两个人都没有做作业。任务被拖延了。

    这时候两个学生采取的策略就不同了:
    schedule重新安排了任务时间,旅游回来的第一天做第11天的任务,第二天做第12天的任务,最后完成任务花了35天。

    scheduleAtFixedRate是个守时的学生,她总想按时完成老师的任务,于是在旅游回来的第一天把之前5天欠下的任务以及第16天当天的任务全部完成了,之后还是按照老师的原安排完成作业,最后完成任务花了30天。

    import java.text.SimpleDateFormat;
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class Test01 {
    public static void main(String[] args) {
        final Timer timer = new Timer();
        //timer.scheduleAtFixedRate(new TimerTask() {
        timer.schedule(new TimerTask() {//分别注释这行和上面这行试一试效果
            int count = 1;
            @Override
            public void run() {
                count++;
                if (count  == 10) {
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        System.out.println("延迟5s");
                        e.printStackTrace();
                    }
                }
                SimpleDateFormat sf = new SimpleDateFormat(
                        "yyyy MM dd hh:mm:ss");
                System.out.println("当前时间:"
                        + sf.format(System.currentTimeMillis()) + "计划时间:"
                        + sf.format(scheduledExecutionTime()));
            }
        }, 1000, 1000);
      }
    }
    

    Timer的缺陷:
    1.管理并发任务的缺陷:每次有且仅有一个线程去执行定时任务,如存在多任务会导致任务时间过长(串行)
    2.当任务抛出异常时的缺陷:当抛出RuntimeException(如果不捕捉异常),会停止所有任务
    3.在以下情况禁止使用
    对时效性要求较高的多任务并发作业/对复杂的任务的调度

    Java定时任务调度工具详解之 Quartz篇

    Quartz特点:
    1.强大的调度功能
    2.灵活的应用方式
    3.分布式和集群能力

    三个核心:Jobdetail(调度器),Trigger(触发器) ,Scheduler (任务),就能轻松使用Quartz;
    JobDetail用来绑定Job,并且在Job执行的时候携带一些执行的信息;
    JobDetail和Tigger通过Builder模式创建;
    Scheduler通过Factory模式创建;

    image.png
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 打印当前的时间,格式为2017-01-01 00:00:00
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("Current Time Is : " + sf.format(date));
        // 创建一个JobDetail实例,将该实例与HelloJob Class绑定
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)
                .withIdentity("myJob").build();
        CronTrigger trigger = (CronTrigger) TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "group1")
                .withSchedule(
                        CronScheduleBuilder.cronSchedule("* * * * * ?"))
                .build();
        // 创建Scheduler实例
        SchedulerFactory sfact = new StdSchedulerFactory();
        Scheduler scheduler = sfact.getScheduler();
        scheduler.start();
        System.out.println("scheduled time is :"
                + sf.format(scheduler.scheduleJob(jobDetail, trigger)));
        //scheduler执行两秒后挂起
        Thread.sleep(2000L);        
        //shutdown(true)表示等待所有正在执行的job执行完毕之后,再关闭scheduler
        //shutdown(false)即shutdown()表示直接关闭scheduler
        scheduler.shutdown(false);
        System.out.println("scheduler is shut down? " + scheduler.isShutdown());
    }
    

    一.浅谈Job&JobDetail

    image.png

    JobDetail为Job提供的重要属性

    可以通过 jobDetail 的 getKey() 方法来获取相关信息
    jobDetail.getKey().getName();    // 获取名称
    jobDetail.getKey().getGroup();    // 获取组名称
    jobDetail.getJobClass.getName()    // 获取Job class 的名称
    jobDataMap //用来存储特定Job实例的状态信息。
    

    二.JobExecutionContext & JobDataMap

    JobExecutionContext
    概念:Job能通过JobExecutionContext访问Quartz运行环境以及Job的明细数据,当Scheduler调用Job时能将数据传递给execute()方法

    JobDataMap
    概念:是一个JDK中Map接口实例,在任务调度时存在于JobExecutionContext中,可将参数对象传递给在运行的Job实例;而且,它自身有方便的方法可存取基本数据类型
    获取方式:从JobDataMap中直接获取、在Job实现类中添加setter方法对应JobDataMap的键值

    未完待续~~~

    https://www.imooc.com/video/15144

    相关文章

      网友评论

        本文标题:Java定时任务调度工具详解

        本文链接:https://www.haomeiwen.com/subject/yhhrzftx.html