精华内容
下载资源
问答
  • Task Scheduler接口抽象

    2017-02-27 00:42:11
    本文主要是简单地描述了一下封装Task Scheduler接口时可能遇到的问题,希望这对大家有所帮助。
     
    

    嗯,关于Task Scheduler的接口抽象,这个就得根据自己项目的需要自行决定了,比如本人由于在“优化加速”模块之中,需求是管理Windows系统内的所有任务计划项的禁用/启用状态,当然,每个任务计划项的描述信息也是要获取,因此,需要抽象出来的接口肯定不多,大致包含了“遍历所有任务计划项”、“禁用指定任务计划项”、“启用指定任务计划项”等等,其中,查询到的任务计划项信息的时机是在搜索的时候获得的,因此,获取任务计划项的详细信息自然都在遍历任务项的时候获取了。所以,这个功能点的工作量其实不大,毕竟所需要做的并不是一个任务计划程序o(∩_∩)o

    另外,正如在《Task Scheduler 1.0/2.0的相关操作》里面看到的,Task Scheduler 1.0/2.0的操作套路其实并没有较大差异。虽然如此,但是我们不能盲目乐观,因为2.0与1.0相比,其底层的架构实现已经有了较大变化,在2.0中,想实现1.0相似的功能,需要操作更多的COM对象,比如获取指定的任务计划项的特定信息,在2.0中,因为引入了类文件系统的特性,把任务计划项们存放在各个ITaskFolder对象对应的路径上,在Win7下要想找到指定任务计划项,知道了任务计划项的内部名称是不行的,还需要提供其所在路径信息,然后找到对应的ITaskFolder对象,然后通过调用此对象的GetTask()来根据内部名称才能检索到所需的任务计划项,而这些在1.0下是不需要的;类似的还有遍历所有任务计划项,在2.0里是递归遍历所有ITaskFolder对象,然后再通过此对象下的GetTasks()函数来遍历此路径下的所有任务计划项的,而1.0则是可以直接通过IEnumWorkItems对象来遍历……

    最终我在项目里实现的接口类图如下所示:
    Task Scheduler功能接口类图

    展开全文
  • SessionValidationScheduler接口

    千次阅读 2016-11-02 08:40:28
    SessionValidationScheduler接口主要用来定义session的有效操作,先对其解析如下: 1.返回任务是否可用(如果任务可用,则返回true;如果任务不可用,则返回false) boolean isEnabled(); 2.使session有效 void ...

    SessionValidationScheduler接口主要用来定义session的有效操作,先对其解析如下:

    1.返回任务是否可用(如果任务可用,则返回true;如果任务不可用,则返回false)

    boolean isEnabled();

    2.使session有效

    void enableSessionValidation();

    3.使session失效

    void disableSessionValidation();

    展开全文
  • YarnScheduler是Yarn所有调度器必须实现的接口,因此,分析它所用的类对于理解调度器的功能,为以后自定义调度器打下了基础。 1. QueueInfo QueueInfo 报告了一个队列在运行时的信息。 它包含以下信息: 队列名称...

    YarnScheduler是Yarn所有调度器必须实现的接口,因此,分析它所用的类对于理解调度器的功能,为以后自定义调度器打下了基础。

    1. QueueInfo

    QueueInfo 报告了一个队列在运行时的信息。
    它包含以下信息:
    队列名称。
    队列中的容量。
    队列的最大容量。
    队列的当前容量。
    子队列。
    正在运行的程序。
    队列的状态。
    
    


    QueueState 是一个枚举类,有两个元素:

      STOPPED --Stopped状态不接受任何新程序。

     RUNNING --正常状态

    public enum QueueState {
      /**
       * Stopped - Not accepting submissions of new applications.
       */
      STOPPED,
      
      /**
       * Running - normal operation.
       */
      RUNNING
    }


    QueueACL是一个枚举类,有两个元素:

      SUBMIT_APPLICATIONS -- 可以把程序提交到这个队列的ACL。

      ADMINISTER_QUEUE -- 管理这个队列的ACL。

    public enum QueueACL {
      /**
       * ACL to submit applications to the queue.
       */
      SUBMIT_APPLICATIONS,
      
      /**
       * ACL to administer the queue.
       */
      ADMINISTER_QUEUE,
    }

    ApplicationAttemptId 就是ApplicationMaster的一次运行尝试,有两个成员,一个是ApplicationId,一个是int attemptId。


    ApplicationId代表一个应用的全局唯一标识,标识的字符串内容为:appIdStrPrefix + this.getClusterTimestamp() + "_"    + appIdFormat.get().format(getId());

    其中:appIdStrPrefix = "application_";

              cluster timestamp = start-time of theResourceManager

              getId() 返回当前程序的ID,程序的ID用一个单向递增的计数器生成,然后再格式化成最少4位数的字符串。

             

    allocate方法是最重要的方法,定义如下所示:

      Allocation 
      allocate(ApplicationAttemptId appAttemptId, 
          List<ResourceRequest> ask,
          List<ContainerId> release, 
          List<String> blacklistAdditions, 
          List<String> blacklistRemovals);

    ResourceRequest: 代表一个应用程序向ResourceManager申请获得各种Container的请求。它包含

      Priority: request的优先级(Priority )

      Location: 所需要容器所在的服务器或者机架的位置。‘*’代表任何服务器都可以。

      Resource: 以上条件下的容器的数量。

      RelaxLocality: 是否可以宽松本地化,默认为true。

    ContainerId: 代表一个容器在集群中的全局唯一标识, 包括ApplicationAttemptId appAttemptId,      long containerId


    SchedulerNodeReport getNodeReport(NodeId nodeId);

    NodeId 是一个结点的唯一标识,包括结点的主机名称和端口。

    SchedulerNodeReport有三个字段,第一个是已经使用了的资源,第二个是未分配的资源,第三个是正在运行的容器数量。

    SchedulerAppReport有三个字段,第一个是正在使用的资源,第二个是保留的资源,第三个是是否处于暂停状态。

    ApplicationResourceUsageReport 有以下字段:

        numUsedContainers:已经使用了的容器数量。

        numReservedContainers:已经保留了的容器数量。

        usedResources:已经使用了的资源。

       reservedResources:保留的资源。

       neededResources: 需要的资源。

       memory_seconds:程序分配的内存乘以运行的时间(以秒计)。

      vcore_seconds:程序分配的cpu数乘以运行的时间(以秒计)。

    public enum RMContainerState {
      NEW, 
      RESERVED, 
      ALLOCATED, 
      ACQUIRED, 
      RUNNING, 
      COMPLETED, 
      EXPIRED, 
      RELEASED, 
      KILLED
    }
    Container代表一个集群中分配了的资源。ResourceManager有对应用分配容器的唯一权威。分配的Container总是在单个结点上,并且有唯一的ContainerId.它有一定量的资源。它包括以下内容:

      ContainerId:全局唯一。

      NodeId: 分配的结点。

      nodeHttpAddress:结点的uri.

      Resource:分配的资源。

      Priority:优先级

      Token:Container的Token.

      一般来说,在资源协商过程中,ApplicationMaster从ResourceManager接收Container,然后和NodeManager交互来启动或者停止Container.

     QueueEntitlement是队列的应得权益。 在FairScheduler中是weights,在CapacityScheduler中代表Capacity.


    展开全文
  • 核心接口如下: 接口 ... scheduler的主要API接口 Job 任务实现接口,期望调度器能够执行 JobDetail 用于定义Job实例 Trigger 调度器基于特定时间来执行指定任务的组件 JobBui...

    参考文章:https://www.cnblogs.com/mengrennwpu/p/7141986.html

    核心接口如下:

    接口含义
    Schedulerscheduler的主要API接口
    Job任务实现接口,期望调度器能够执行
    JobDetail用于定义Job实例
    Trigger调度器基于特定时间来执行指定任务的组件
    JobBuilder  用于定义、创建JobDetail实例
    TriggerBuilder用于定义、创建Trigger实例

    1、Scheduler

           调度器Scheduler就相当于一个容器,装载着任务和触发器。该类是一个接口,代表一个 Quartz 的独立运行容器, Trigger 和 JobDetail 可以注册到 Scheduler 中, 两者在 Scheduler 中拥有各自的组及名称, 组及名称是 Scheduler 查找定位容器中某一对象的依据, Trigger 的组及名称必须唯一, JobDetail 的组和名称也必须唯一(但可以和 Trigger 的组和名称相同,因为它们是不同类型的)。Scheduler 定义了多个接口方法, 允许外部通过组及名称访问和控制容器中 Trigger 和 JobDetail。

           Scheduler 可以将 Trigger 绑定到某一 JobDetail 中, 这样当 Trigger 触发时, 对应的 Job 就被执行。一个 Job 可以对应多个 Trigger, 但一个 Trigger 只能对应一个 Job。可以通过 SchedulerFactory 创建一个 Scheduler 实例。Scheduler 拥有一个 SchedulerContext,保存着 Scheduler 上下文信息,Job 和 Trigger 都可以访问 SchedulerContext 内的信息。SchedulerContext 内部通过一个 Map,以键值对的方式维护这些上下文数据,SchedulerContext 为保存和获取数据提供了个 put() 和 getXxx() 的方法。可以通过 Scheduler.getContext() 获取对应的 SchedulerContext 实例。

           一个调度器的生命周期为通过SchedulerFactory创建,直到执行其shutdown()方法。当Scheduler创建之后,可以进行增加、删除及显示任务Job与触发器Trigger,并且执行其他的调度相关的操作,如暂停一个触发器Trigger。需要注意的是,直到调用start()方法时,Scheduler才正式开始执行job和trigger。

           StdSchedulerFactory用于创建Scheduler,其依赖于一系列的属性来决定如何产生Scheduler。可以通过四种途径向StdSchedulerFactory提供属性配置信息。

    1.1 通过java.util.Properties初始化StdSchedulerFactory

           在Quzrtz学习总结一之快速体验的工程基础上,创建一个包com.zdw.zixue.scheduler,该包用来测试通过四种方式来初始化StdSchedulerFactory对象

    package com.zdw.zixue.scheduler;
    
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.impl.StdSchedulerFactory;
    
    import java.util.Properties;
    
    public class SchedulerDemo1 {
        public static void main(String[] args) {
            //创建StdSchedulerFactory实例
            StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
    
            //创建配置工厂的属性对象
            Properties properties = new Properties();
            properties.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS,"org.quartz.simpl.SimpleThreadPool");//定义线程池
            properties.put("org.quartz.threadPool.threadCount","10");//默认Scheduler的线程数
    
            try {
                //使用属性对象初始化工厂
                stdSchedulerFactory.initialize(properties);
                //创建调度容器Scheduler
                Scheduler scheduler = stdSchedulerFactory.getScheduler();
                //启动调度容器
                scheduler.start();
                System.out.println("调度容器的元数据:"+scheduler.getMetaData());
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    }

    执行,控制台打印:

    调度容器的元数据:Quartz Scheduler (v2.2.3) 'QuartzScheduler' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'org.quartz.impl.StdScheduler' - running locally.
      Running since: Wed Sep 25 16:07:27 CST 2019
      Not currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

    可以看到对应的配置属性已经生效。

           通过Properties设置工厂属性的缺点在用硬编码,假如需要修改例子中线程数量,将不得不修改代码,然后重新编译。后面几种方法可以解决硬编码的问题。

    1.2 通过外部属性文件初始化StdSchedulerFactory

    假设在D盘的根目录下有一个文件:properties.properties,(文件名随意),里面的内容如下:

    org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
    org.quartz.threadPool.threadCount=5
    package com.zdw.zixue.scheduler;
    
    import org.quartz.Scheduler;
    import org.quartz.SchedulerException;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class SchedulerDemo2 {
        public static void main(String[] args) {
            //创建StdSchedulerFactory实例
            StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
    
            try {
                //使用外部属性文件初始化工厂
                stdSchedulerFactory.initialize("d:/properties.properties");
                //创建调度容器Scheduler
                Scheduler scheduler = stdSchedulerFactory.getScheduler();
                //启动调度容器
                scheduler.start();
                System.out.println("2--调度容器的元数据:"+scheduler.getMetaData());
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
        }
    }

    执行结果:

    2--调度容器的元数据:Quartz Scheduler (v2.2.3) 'QuartzScheduler' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'org.quartz.impl.StdScheduler' - running locally.
      Running since: Wed Sep 25 16:11:48 CST 2019
      Not currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 5 threads.
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

    1.3 通过含有属性文件内容的java.io.InputStream初始化StdSchedulerFactory

    假设在D盘的根目录下有一个文件:properties.properties,(文件名随意),里面的内容如下:

    org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
    org.quartz.threadPool.threadCount=5
    package com.zdw.zixue.scheduler;
    
    import org.quartz.Scheduler;
    import org.quartz.impl.StdSchedulerFactory;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    
    public class SchedulerDemo3 {
        public static void main(String[] args) {
            //创建StdSchedulerFactory实例
            StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
            try {
                //得到D盘下的配置文件properties.properties的字节流
                InputStream inputStream = new FileInputStream(new File("d:/properties.properties"));
                //使用含有属性文件内容的java.io.InputStream初始化工厂
                stdSchedulerFactory.initialize(inputStream);
                //创建调度容器Scheduler
                Scheduler scheduler = stdSchedulerFactory.getScheduler();
                //启动调度容器
                scheduler.start();
                System.out.println("3---调度容器的元数据:"+scheduler.getMetaData());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    执行结果:

    3--调度容器的元数据:Quartz Scheduler (v2.2.3) 'QuartzScheduler' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'org.quartz.impl.StdScheduler' - running locally.
      Running since: Wed Sep 25 16:25:49 CST 2019
      Not currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 5 threads.
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

    1.4 通过quartz.properties配置文件初始化StdSchedulerFactory

    这是推荐使用的方式,也是开发中经常使用的方式。

           如果调用无参的initialize方法,StdSchedulerFactory会试图从quartz.properties的文件中加载。quartz.properties相关配置后续文章会介绍,注意quartz.properties的加载顺序为:

    a. 检查System.getProperty("org.quartz.properties")中是否设置其他属性文件名

    b. 如果a未设置,则将会从当前工作目录中加载quartz.properties配置文件

    c. 如果b未找到,则试图从系统的classpath中加载该配置文件。

           Scheduler在生命周期中也可执行其他操作,如查询、设置standby模式、继续执行、停止执行。standby模式会导致Scheduler暂时停止查找Job去执行。standby模式的设置直接使用scheudler.standby()即可。

           Scheduler的停止方法为shutdown()方法,也可以使用有参shutdown(false),其中参数表示是否让当前正在进行的job正常执行完成才停止Scheduler。

     

    本次,我们在工程的resources目录下面创建quartz.properties文件,内容如下:

    org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
    org.quartz.threadPool.threadCount=8
    package com.zdw.zixue.scheduler;
    
    import org.quartz.Scheduler;
    import org.quartz.impl.StdSchedulerFactory;
    
    public class SchedulerDemo4 {
        public static void main(String[] args) {
            //创建StdSchedulerFactory实例
            StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
            try {
                //使用classpath下的quartz.properties配置文件初始化工厂
                stdSchedulerFactory.initialize();
                //创建调度容器Scheduler
                Scheduler scheduler = stdSchedulerFactory.getScheduler();
                //启动调度容器
                scheduler.start();
                System.out.println("4--调度容器的元数据:"+scheduler.getMetaData());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    执行结果:

    4--调度容器的元数据:Quartz Scheduler (v2.2.3) 'QuartzScheduler' with instanceId 'NON_CLUSTERED'
      Scheduler class: 'org.quartz.impl.StdScheduler' - running locally.
      Running since: Wed Sep 25 16:35:30 CST 2019
      Not currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 8 threads.
      Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

     

    2、Job

          定义需要执行的任务。该类是一个接口,只定义一个方法 execute(JobExecutionContext context),在实现类的 execute 方法中编写所需要定时执行的 Job(任务), JobExecutionContext 类提供了调度应用的一些信息,JobExecutionContext对象让Job能访问Quartz运行时环境的所有信息和Job本身的明细数据。运行时环境信息包括注册到Scheduler上与该Job相关联的JobDetail和Trigger。

    修改Quzrtz学习总结一之快速体验的工程中的FirstJob.java文件,如下:

    package com.zdw.zixue.job;
    
    import org.quartz.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * Job实现类,任意java类实现Job接口就行了
     */
    public class FirstJob implements Job {
    
        private static Logger logger = LoggerFactory.getLogger(FirstJob.class);//日志对象
    
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            System.out.println("----------Hello World--------------");
    
            // 每一个Job都有其自己所属的JobDetail
            JobDetail jobDetail = context.getJobDetail();
            //JobDetail的名称和组名
            System.out.println("JobDetail的名称和组名:"+jobDetail.getKey());
    
            // 获取Scheduler
            Scheduler scheduler = context.getScheduler();
            try {
                System.out.println("调度器Scheduler name: "+scheduler.getSchedulerName());
            } catch (SchedulerException e) {
                e.printStackTrace();
            }
    
            // 具体job的类全名
            System.out.println("job的类全名:"+jobDetail.getJobClass());
    
            // 本次任务执行时间
            System.out.println("本次任务执行时间:"+context.getFireTime());
    
            // 下次任务执行时间
            System.out.println("下次任务执行时间:"+context.getNextFireTime());
    
            // 获取jobDetail的参数信息
            System.out.println("参数信息:"+jobDetail.getJobDataMap().get("message"));
        }
    }

    再次运行FirstJobTest,结果:

    ----------创建调度任务成功----------
    ----------Hello World--------------
    JobDetail的名称和组名:first_group.first_job
    调度器Scheduler name: QuartzScheduler
    job的类全名:class com.zdw.zixue.job.FirstJob
    本次任务执行时间:Wed Sep 25 16:49:57 CST 2019
    下次任务执行时间:Wed Sep 25 16:50:07 CST 2019
    参数信息:null
    ----------Hello World--------------
    JobDetail的名称和组名:first_group.first_job
    调度器Scheduler name: QuartzScheduler
    job的类全名:class com.zdw.zixue.job.FirstJob
    本次任务执行时间:Wed Sep 25 16:50:07 CST 2019
    下次任务执行时间:Wed Sep 25 16:50:17 CST 2019
    参数信息:null
    ----------Hello World--------------
    JobDetail的名称和组名:first_group.first_job
    调度器Scheduler name: QuartzScheduler
    job的类全名:class com.zdw.zixue.job.FirstJob
    本次任务执行时间:Wed Sep 25 16:50:17 CST 2019
    下次任务执行时间:Wed Sep 25 16:50:27 CST 2019
    参数信息:null
    ----------Hello World--------------
    JobDetail的名称和组名:first_group.first_job
    调度器Scheduler name: QuartzScheduler
    job的类全名:class com.zdw.zixue.job.FirstJob
    本次任务执行时间:Wed Sep 25 16:50:27 CST 2019
    下次任务执行时间:Wed Sep 25 16:50:37 CST 2019
    参数信息:null
    ---------------关闭了调度器----------------

    3、JobDetail

           描述 Job 的实现类及其它相关的静态信息,如:Job 名字、描述、关联监听器等信息。Quartz 每次调度 Job 时, 都重新创建一个 Job 实例, 所以它不直接接受一个 Job 的实例,相反它接收一个 Job 实现类,以便运行时通过 newInstance() 的反射机制实例化 Job。

    3.1 Job简述

           JobDetail是作为Job实例进行定义的,注意部署在Scheduler上的每一个Job只创建一个JobDetail实例。且需要注意的是注册到Scheduler上的不是Job对象,而是JobDetail实例。

          Job 的实例要到该执行它们的时候才会实例化出来。每次 Job 被执行,一个新的 Job 实例会被创建。其中暗含的意思就是你的 Job 不必担心线程安全性,因为同一时刻仅有一个线程去执行给定 Job 类的实例,甚至是并发执行同一 Job 也是如此。

           可以使用JobDataMap来定义Job的状态,JobDataMap中可以存入key-value对,这些数据可以在Job实现类中进行传递和访问。这是向你的Job传送配置信息的便捷方法。

          Job 能通过 JobExecutionContext 对象访问 JobDataMap

    修改Quzrtz学习总结一之快速体验的工程中的FirstJobTest.java文件,把睡眠时间修改为20s,并且把类QuartzServer中的createJobDetail方法修改为:

    //创建JobDetail
        public static JobDetail createJobDetail(){
            JobDetail jobDetail = JobBuilder.newJob(FirstJob.class)//设置执行任务的类
                    .withIdentity("first_job", "first_group")//job名称与job组名称组成Scheduler中任务的唯一标识
                    .usingJobData("message","我是第一个job的参数")//设置参数信息
                    .build();//构建
            return jobDetail;
        }

    运行结果:

    ----------创建调度任务成功----------
    ----------Hello World--------------
    JobDetail的名称和组名:first_group.first_job
    调度器Scheduler name: QuartzScheduler
    job的类全名:class com.zdw.zixue.job.FirstJob
    本次任务执行时间:Wed Sep 25 17:02:26 CST 2019
    下次任务执行时间:Wed Sep 25 17:02:36 CST 2019
    参数信息:我是第一个job的参数
    ----------Hello World--------------
    JobDetail的名称和组名:first_group.first_job
    调度器Scheduler name: QuartzScheduler
    job的类全名:class com.zdw.zixue.job.FirstJob
    本次任务执行时间:Wed Sep 25 17:02:36 CST 2019
    下次任务执行时间:Wed Sep 25 17:02:46 CST 2019
    参数信息:我是第一个job的参数
    ----------Hello World--------------
    JobDetail的名称和组名:first_group.first_job
    调度器Scheduler name: QuartzScheduler
    job的类全名:class com.zdw.zixue.job.FirstJob
    本次任务执行时间:Wed Sep 25 17:02:46 CST 2019
    下次任务执行时间:Wed Sep 25 17:02:56 CST 2019
    参数信息:我是第一个job的参数
    ---------------关闭了调度器----------------

    可以看到,在FirstJob中,可以获取到我们设置的参数message的值。

           如果你使用的是持久化的存储机制(本教程的JobStore部分会讲到),在决定JobDataMap中存放什么数据的时候需要小心,因为JobDataMap中存储的对象都会被序列化,因此很可能会导致类的版本不一致的问题;Java的标准类型都很安全,如果你已经有了一个类的序列化后的实例,某个时候,别人修改了该类的定义,此时你需要确保对类的修改没有破坏兼容性;

    3.2 有状态Job和无状态Job

           有状态的Job可以理解为多次Job调用期间可以持有一些状态信息,这些状态信息存储在JobDataMap中,而默认的无状态job每次调用时都会创建一个新的JobDataMap。

    3.2.1 有状态的Job示例

    靠注解@PersistJobDataAfterExecution实现

    修改类QuartzServer中的createJobDetail方法,设置参数的值,如下:

    //创建JobDetail
        public static JobDetail createJobDetail(){
            JobDetail jobDetail = JobBuilder.newJob(FirstJob.class)//设置执行任务的类
                    .withIdentity("first_job", "first_group")//job名称与job组名称组成Scheduler中任务的唯一标识
                    //.usingJobData("message","我是第一个job的参数")//设置参数信息
                    .usingJobData("count",0)//设置参数
                    .build();//构建
            return jobDetail;
        }

    FirstJob修改为如下:

    package com.zdw.zixue.job;
    
    import org.quartz.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    @PersistJobDataAfterExecution//添加了这个注解
    public class FirstJob implements Job {
        private static Logger logger = LoggerFactory.getLogger(FirstJob.class);//日志对象
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
    
            int count = jobDataMap.getInt("count");
            System.out.println("count: "+count);
            ++count;
            jobDataMap.put("count", count);
        }
    }

    运行结果:

    ----------创建调度任务成功----------
    count: 0
    count: 1
    count: 2
    ---------------关闭了调度器----------------

    3.2.2 无状态的Job示例

    不加注解@PersistJobDataAfterExecution

    package com.zdw.zixue.job;
    
    import org.quartz.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class FirstJob implements Job {
        private static Logger logger = LoggerFactory.getLogger(FirstJob.class);//日志对象
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
    
            int count = jobDataMap.getInt("count");
            System.out.println("count: "+count);
            ++count;
            jobDataMap.put("count", count);
        }
    }

    运行结果:

    ----------创建调度任务成功----------
    count: 0
    count: 0
    count: 0
    ---------------关闭了调度器----------------

    可见 @PersistJobDataAfterExecution的作用在于持久化保存在JobDataMap中的传递参数,使得多次执行Job,可以获取传递参数的状态信息。

    Job 有一个 StatefulJob 子接口(Quartz 2 后用 @PersistJobDataAfterExecution 注解代替),代表有状态的任务,该接口是一个没有方法的标签接口,其目的是让 Quartz 知道任务的类型,以便采用不同的执行方案。

    • 无状态任务在执行时拥有自己的 JobDataMap 拷贝,对 JobDataMap 的更改不会影响下次的执行。

    • 有状态任务共享同一个 JobDataMap 实例,每次任务执行对 JobDataMap 所做的更改会保存下来,后面的执行可以看到这个更改,也即每次执行任务后都会对后面的执行发生影响。

    正因为这个原因,无状态的 Job 并发执行,而有状态的 StatefulJob 不能并发执行。这意味着如果前次的 StatefulJob 还没有执行完毕,下一次的任务将阻塞等待,直到前次任务执行完毕。有状态任务比无状态任务需要考虑更多的因素,程序往往拥有更高的复杂度,因此除非必要,应该尽量使用无状态的 Job。

     

    3.3 @DisallowConcurrentExecution 

           quartz中另一个常用的注解为@DisallowConcurrentExecution,该注解可以同一个时刻,同一个任务只能执行一次,不能并行执行两个或多个同一任务。但需要注意的是,多个不同的任务是可以同时执行的。

    展开全文
  • spring 3.0版本后,自带了一个定时任务工具,而且使用简单方便,不用配置文件,可以...TaskScheduler接口 TaskScheduler是一个接口 TaskScheduler接口下定义了6个方法 schedule(Runnable task, Trigger trigger); ...
  • scheduler的主要API接口 Job 任务实现接口,期望调度器能够执行 JobDetail 用于定义Job实例 Trigger 调度器基于特定时间来执行指定任务的组件 JobBuilder  用于定义、创建JobDetail实例 ...
  • scheduleR是一个框架,可用于部署 R 任务、报告和应用程序。 任务是您希望安排定期执行的“常规”R 脚本(通常是与 ETL 相关的脚本)。 报告是可以转换为 PDF 或 HTML 的 Rmarkdown (.Rmd) 报告。 有关更多信息,...
  • windows任务Task Scheduler的命令行接口

    千次阅读 2019-06-03 15:00:06
    有两个,一个是众所周知的at命令;还有一个是更高级的、替代at的schtasks命令。C:>schtasks /?SCHTASKS /parameter [arguments]描述:允许管理员创建、删除、查询、更改、运行和...
  • 最近工作不是很忙,抽空整合了以前的老代码,编写一套在Unity游戏开发中使用的统一调用接口。Unity2018 版本后支持.net 4.0+,这套调度接口也利用了多线程并行运行的机制来提高整体的运行效率,虽然在客户端中实际上...
  • 文章目录概述TaskExecutor 接口概览简单分析TaskScheduler 接口概览简单分析Trigger 接口概览简单分析实现Xml配置实现注解实现集成 SpringBoot (Java Config 实现)参考 概述 在 Spring 中提供的定时任务处理模块为 ...
  • scheduler的主要API接口 Job 任务实现接口,期望调度器能够执行 JobDetail 用于定义Job实例 Trigger 调度器基于特定时间来执行指定任务的组件 JobBuilder  用于定义、创建JobDetail实例 ...
  • Spring基础学习-任务调度TaskScheduler

    千次阅读 2018-03-12 19:16:54
    某些时候我们可能需要在某些固定的时间或者是间隔一定的时间连续执行一些任务,如每天凌晨自动跑一些批次/心跳检测等。...2 TaskScheduler接口简介 2.1 接口简介 2.2 TaskScheduler的实现类 2.2...
  • 概述 集群资源是非常有限的,在多用户、多任务环境下,需要有一个协调者,来保证...YARN资源调度器均实现Resource Scheduler接口,是一个插拔式组件,用户可以通过配置参数来使用不同的调度器,也可以自己按照接口...
  • 这是一个简单的作业计划程序,具有HTTP接口和MySQL作为数据库。 环境 您可以使用以下命令安装此服务器: go get github.com/infiniteloopsco/guartz 浏览到guartz目录并安装依赖项: godep restore 构建二进制文件...
  • PyTorch学习率调整策略通过torch.optim.lr_scheduler接口实现。PyTorch提供的学习率调整策略分为三大类,分别是 有序调整:等间隔调整(Step),按需调整学习率(MultiStep),指数衰减调整(Exponential)和余弦退火...
  • 2. 相当于每次调用接口的时候先登录 用户登录 -------> 返回获取header 头中获取token 然后在通过token 调用其他接口 合理的方法是: 每次登录后将获取到的token 存到redis 中然后其他接口在调用的时候先从...
  • Spring框架使用TaskExecutor和TaskScheduler接口分别为异步执行和任务调度提供抽象。 Spring还提供了那些接口的实现,这些接口在应用服务器环境中支持线程池或委托给CommonJ。 最终,在公共接口背后使用这些实现...
  • 具有用于计划和取消作业的HTTP接口。 在作业的执行时间向config中定义的端点发出POST请求。 重试失败的作业,具有恒定或指数补偿。 可以运行多个实例以实现高可用性和横向扩展。 安装 使用预先构建的Docker映像...
  • JobScheduler简介

    万次阅读 2017-12-09 15:52:15
    JobScheduler机制简析1.概述JobScheduler主要用于在未来某个时间下...JobScheduler提供了接口来调度各种类型的工作,在应用进程中执行。JobInfo里面包含了很多关于工作的信息,可以将JobInfo传递给JobScheduler的schedu
  • lr_scheduler 学习率 学习率的参数调整是深度学习中一个非常重要的一项,Andrew NG(吴恩达)认为一般如果...PyTorch学习率调整策略通过torch.optim.lr_scheduler接口实现。PyTorch提供的学习率调整策略分为三大类,...
  • 浅谈Scheduler

    万次阅读 2019-09-26 18:09:18
    转载地址:... 1.Scheduler工厂模式 所有的Scheduler实例应该由SchedulerFactory来创建 2.SchedulerFactory类图  最常用的是StdSchedulerFactory工程类,其出那个键Scheduler的两种方式: ...
  • TaskScheduler相关

    2020-04-08 23:49:44
    1、DAGScheduler与TaskScheduler 2、TaskScheduler与SchedulerBackend 3、任务调度过程总结 1、DAGScheduler与TaskScheduler DAGScheduler面向我们整个Job划分出了Stage,划分了Stage是从后往前划分的,执行的...
  • 调度器 Scheduler

    千次阅读 2016-03-21 08:32:21
    调度器 Scheduler如果你想给Observable操作符链添加多线程功能,你可以指定操作符(或者特定的Observable)在特定的调度器(Scheduler)上执行。某些ReactiveX的Observable操作符有一些变体,它们可以接受一个...
  • Spark-scheduler

    千次阅读 2015-05-21 22:47:01
    Spark-scheduler@(spark)[scheduler]Task/**

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 50,346
精华内容 20,138
关键字:

scheduler接口