`

spring日记(十):任务调度和异步执行器

阅读更多

博客新地址:http://yidao620c.github.io

 

>> 在spring中使用quartz

创建JobDetailBean:

<!-- 通过JobDetailBean实现 -->
<bean name="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"
    p:jobClass="com.baobaotao.quartz.MyJob"
    p:applicationContextJobDataKey="applicationContext">
    <property name="jobDataAsMap">
        <map>
            <entry key="size" value="10" />
        </map>
    </property>
</bean>

在JobDetailBean中有几个属性:

jobClass:类型为Class,实现了Job接口的任务类

beanName:显示指定Bean名称,没啥用处

jobDataAsMap:类型为Map,为任务所对应的JobDataMap提供值。

applicationContextJobDataKey:用户可以通过这个key值将Spring的ApplicationContext的引用保存在里面。

jobListenerNames:类型为String[],指定注册在Schedule中的JobListeners名称。

下面是MyJob定义:

import java.util.Map;
 
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;
import org.springframework.context.ApplicationContext;
 
public class MyJob implements StatefulJob {
    public void execute(JobExecutionContext jctx) throws JobExecutionException {
//      Map dataMap = jctx.getJobDetail().getJobDataMap();
        Map dataMap = jctx.getTrigger().getJobDataMap();
        String size =(String)dataMap.get("size");
        ApplicationContext ctx = (ApplicationContext)dataMap.get("applicationContext");
        System.out.println("size:"+size);
        dataMap.put("size",size+"0");
         
        String count =(String)dataMap.get("count");
        System.out.println("count:"+count);
    }
}

如果MyJob实现的是StatefulJob,那么里面的JobDataMap为共享公共变量,下次执行的时候还可以获得同样的,这个不是线程安全的,最好都用无状态的Job

>> 利用MethodInvokingJobDetailFactoryBean直接将某个bean的方法定义成任务执行的动作,也就是说不需要定义JobDetail了,直接将某个bean的方法变成job的execute方法:

<!-- 通过封装服务类方法实现 -->
<bean id="jobDetail_1"
    class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
    p:targetObject-ref="myService" p:targetMethod="doJob" p:concurrent="false" />
 
<bean id="myService" class="com.baobaotao.service.MyService" />

>> 创建Trigger:

* SimpleTriggerBean

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"
    p:jobDetail-ref="jobDetail" p:startDelay="1000" p:repeatInterval="2000"
    p:repeatCount="100">
    <property name="jobDataAsMap">
        <map>
            <entry key="count" value="10" />
        </map>
    </property>
</bean>

SimpleTriggerBean在SimpleTrigger基础上增加了以下属性:

jobDetail:对应的JobDetail

beanName:默认为bean的id,不过之前用beanName属性显示指定了名称的也可以用这个

jobDetailAsMap:以Map类型为Trigger关联的JobDataMap提供值

startDelay:延迟多少时间触发,单位为毫秒,默认为0

triggerListenerNames:类型为String[],不解释了

>> CronTriggerBean

<bean id="checkImagesTrigger"
      class="org.springframework.scheduling.quartz.CronTriggerBean"
      p:jobDetail-ref="jobDetail"
      p:cronExpression="0/5 * * * * ?"/>

>> 创建Scheduler

spring提供了ScheduleFactoryBean,可以在spring容器启动后,Scheduler自动开始工作,而在spring容易关闭前,自动关闭Scheduler

<bean id="scheduler"
    class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
        <list>
            <ref bean="simpleTrigger" />
        </list>
    </property>
    <property name="schedulerContextAsMap">
        <map>
            <entry key="timeout" value="30" />
        </map>
    </property>
    <property name="configLocation" value="classpath:com/baobaotao/quartz/quartz.properties" />
    <property name="quartzProperties">
        <props>
            <prop key="org.quartz.threadPool.class">
                org.quartz.simpl.SimpleThreadPool
            </prop>
            <prop key="org.quartz.threadPool.threadCount">10</prop>
        </props>
    </property>
</bean>

SchedulerFactoryBean还拥有一些常见的属性:

* calendars:类型为Map,通过该属性向Scheduler注册Calendar

* jobDetails:类型为JobDetail[],注册JobDetail

* autoStartup:是否马上启动Scheduler,默认为true

* startupDelay:延迟多少秒启动Scheduler

* dataSource:当需要数据库持久化任务调度数据时候用到

* transactionManager:当配一个dataSource后,应该同步配置这个

* nonTransactionalDataSource:无事务的数据源

* quartzProperties:允许用户在spring中定义Quartz属性,覆盖quartz.properties文件中的定义

>> spring对于JDK5中的Executor的支持

JDK5本身提供的ThreadPoolExecutor类实现了Executor和ExecutorService这两个接口,它使用一个线程池对提交的任务进行调度,对于需要处理数量巨大的短小并发任务如Web服务器、数据库服务器、邮件服务器之类的应用程序需要处理大量来自远程的大量短小任务,采用线程池可以带来明显好处。

ScheduledThreadPoolExecutor是ThreadPoolExecutor的子类,并实现了ScheduledExecutorService接口,添加了对任务的调度功能,该类明显优于JDK1.3中的Timer,因为在内部用线程池,对每次到来的任务用一个新线程去执行,而不是像TImer那么,要等这个任务执行完,才能执行下一个任务,很好的解决了Timer经常出现的时间漂移、任务挤压等问题。

工厂类Executors有很多方法很方便的创建这些线程池:

* public static  ExecutorService newFixedThreadPool(int nThreads):固定数目的线程数量

* public static ExecutorService newCachedThreadPool():线程池动态的,不够就创建新的,长时间不用就回收

* public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) :创建一个线程池,可以在指定延迟后运行或定期执行任务

import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
 
public class ExecutorExample {
    private TaskExecutor executor;
    public void setExecutor(TaskExecutor executor) {
        this.executor = executor;
    }
    public void executeTasks() {
        for (int i = 0; i < 6; i++) {
            executor.execute(new SimpleTask("task" + i));
        }
    }
    public static void main(String[] args) {
        ExecutorExample ee = new ExecutorExample();
        ee.setExecutor(new SimpleAsyncTaskExecutor());
        ee.executeTasks();
    }
}
class SimpleTask implements Runnable {
    private String taskName;
    public SimpleTask(String taskName) {
        this.taskName = taskName;
    }
    public void run() {
        System.out.println("do " + taskName + "... in Thread:"
                + Thread.currentThread().getId());
    }
}
分享到:
评论

相关推荐

    Java课程实验 Spring Boot 任务管理(源代码+实验报告)

    使用@Async注解可以将普通的方法异步执行,使其成为一个异步任务。可以在方法上添加@Async注解并配合@EnableAsync注解将其激活。 4.使用第三方库,如Quartz: 除了使用Spring Boot提供的任务管理功能外,可以使用第...

    Spring任务执行和调度

    Spring框架分别使用TaskExecutor和TaskScheduler接口提供异步执行和任务调度的抽象。Spring还提供了这些接口的实现,这些接口支持线程池或将其委托给应用服务器环境中的CommonJ。 Spring2.0开始引入的新的抽像。...

    Job Plus项目是基于SpringBoot+Vue的轻量级定时任务管理系统+源代码+文档说明

    31. 全异步:任务调度流程全异步化设计实现,如异步调度、异步运行、异步回调等,有效对密集调度进行流量削峰,理论上支持任意时长任务的运行; 32. 跨语言:系统提供语言无关的 RESTFUL API 服务,第三方任意语言可...

    《精通Spring2.X企业应用开发详解》随书源码1-15章

    使用JPA访问数据库 第12章 整合其他ORM框架 第4篇 业务层应用 第13章 任务调度和异步执行器 第14章 JavaMail发送邮件 第15章 在Spring中使用JMS 第16章 在Spring中开发Web Service 第17章 使用...

    《精通Spring2.X企业应用开发详解》16-19章

    使用JPA访问数据库 第12章 整合其他ORM框架 第4篇 业务层应用 第13章 任务调度和异步执行器 第14章 JavaMail发送邮件 第15章 在Spring中使用JMS 第16章 在Spring中开发Web Service 第17章 使用...

    《精通Spring2.X企业应用开发详解》20-23

    使用JPA访问数据库 第12章 整合其他ORM框架 第4篇 业务层应用 第13章 任务调度和异步执行器 第14章 JavaMail发送邮件 第15章 在Spring中使用JMS 第16章 在Spring中开发Web Service 第17章 使用...

    rqueue:Spring框架的Rqueue aka Redis队列[任务队列,消息代理]

    Rqueue:Redis队列,任务队列,Spring和Spring Boot的延迟队列 Rqueue是基于Redis支持的spring框架的消息传递库,为spring框架构建的异步任务执行器(工作程序)。 它也可以用作消息代理,其中所有服务代码都在...

    Spring-Reference_zh_CN(Spring中文参考手册)

    6.1.2. Spring AOP的功能和目标 6.1.3. Spring的AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点(pointcut) 6.2.3.1. 切入点指定者的支持 6.2.3.2. 合并切入点...

    Spring.3.x企业应用开发实战(完整版).part2

    第13章 任务调度和异步执行器 13.1 任务调度概述 13.2 Quartz快速进阶 13.2.1 Quartz基础结构 13.2.2 使用SimpleTrigger 13.2.3 使用CronTrigger 13.2.4 使用Calendar 13.2.5 任务调度信息存储 13.3 在Spring中使用...

    Spring 2.0 开发参考手册

    6.1.2. Spring AOP的功能和目标 6.1.3. Spring的AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点(pointcut) 6.2.4. 声明通知 6.2.5. 引入(Introductions)...

    Spring中文帮助文档

    6.1.2. Spring AOP的功能和目标 6.1.3. AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点(pointcut) 6.2.4. 声明通知 6.2.5. 引入(Introduction) 6.2.6. ...

    Spring API

    2. Spring 2.0和 2.5的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 新的bean作用域 2.2.2. 更简单的XML配置 2.2.3. 可扩展的XML编写 2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件...

    spring chm文档

    Spring Framework 开发参考手册 Rod Johnson Juergen Hoeller Alef Arendsen Colin Sampaleanu Rob Harrop Thomas Risberg Darren Davison Dmitriy Kopylenko Mark Pollack Thierry Templier Erwin ...

    Spring3.x企业应用开发实战(完整版) part1

    第13章 任务调度和异步执行器 13.1 任务调度概述 13.2 Quartz快速进阶 13.2.1 Quartz基础结构 13.2.2 使用SimpleTrigger 13.2.3 使用CronTrigger 13.2.4 使用Calendar 13.2.5 任务调度信息存储 13.3 在Spring中使用...

    java类加载修改源码-jqm:异步作业管理器

    java类加载修改源码质量管理 恰如其分地命名的作业队列管理器,或简称 JQM,是一个队列管理器。 它有三个目标: 通过使用配置丰富的队列来优化和简化作业的执行,无论它们是什么 ...应用程序服务器中删除异步执行

    java8rt.jar源码-gracefullyshutdown:侧重Spring-boot相关的优雅关机思考

    当程序运行时,操作系统调度器加载到内存,分配进程ID,进入待执行状态,当程序分配到时间片后,CPU的程序计数器PC指向进程代码的入口地址,依次执行后加一,保证程序正序执行。如果有中断,进程进入暂停,保留现场...

    【分布式事务----LCN】LCN原理及使用方式.docx

    TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务...

    mybatis-r2dbc:MyBatis R2DBC适配器

    MyBatis R2DBC工作原理对数据CRUD操作SqlSession接口进行Reactive化,对于R2DBC适配来说为ReactiveSqlSessionMapper接口Reactive化,将函数的类型从对象和List调整为Mono和FluxSQL的执行器调整为R2DBC的接口,这里...

    java开源包1

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包11

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

Global site tag (gtag.js) - Google Analytics