首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

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

2013-04-12 
spring日记(十):任务调度和异步执行器 在spring中使用quartz创建JobDetailBean:!-- 通过JobDetailBean

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

>> 在spring中使用quartz

创建JobDetailBean:

<!-- 通过JobDetailBean实现 --><bean name="jobDetail" 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"    p:targetMethod="doJob" p:concurrent="false" /> <bean id="myService" />

>> 创建Trigger:

* SimpleTriggerBean

<bean id="simpleTrigger" 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"      style="border: 0px; padding: 0px; width: 620px; margin-top: 1em !important; margin-right: 0px !important; margin-left: 0px !important; overflow: auto !important; font-size: 1em !important; background-color: white !important;">
<bean id="scheduler"    />        </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());    }}

热点排行