java作业调度、定时任务实践

 


最近项目中用到了定时任务,以前没有接触过,在此对java中定时任务的实现进行总结。

 

实现定时任务的方式有2种,一种是使用java类库中的java.util.Timer;另一种是使用quartz框架。

 

Timer只能实现简单的任务调度,quartz可以满足各种复杂的任务调度时间需求。

 

1、Timer的实现方式

 

在Timer中存在一个任务(Task)的概念,通过继承java.util.TimerTask实现,代码如下:

 



JobScheduler定时后台任务 android java定时任务job_spring



  1. <span style="font-size: 14px;">public class MyTask extends
  2.   
  3. @Override
  4. public void
  5. "execute my task!");  
  6.     }  
  7.   
  8. }</span>  



 

 然后使用Timer实例实现任务的触发和调度,代码如下:

 



JobScheduler定时后台任务 android java定时任务job_spring



  1. <span style="font-size: 14px;">public class
  2.       
  3. public static void
  4. new
  5. // 1秒钟后开始第一次,以后每隔2秒执行一次
  6. new MyTask(), 1000, 2000);  
  7.     }  
  8.   
  9. }</span>  



 

Timer的定时任务实现就这么简单。

 

原理:

1)通过源码可知Timer使用队列(TaskQueue)和线程(TimerThread)实现任务的调度;

2)使用Wait-Notify机制实现队列的阻塞操作;

 

 

 2、quartz实现方式

 

Quartz 是个开源的作业调度框架,为java应用程序的作业调度提供了简单却强大的机制。

 

在quartz中存在一下几个概念:

1)job,相当于timer的task;

2)Trigger(触发器),用来执行job

3)Scheduler(调度器),用来管理Trigger

 

下面是一个简单例子:

 



JobScheduler定时后台任务 android java定时任务job_spring


1. <span style="font-size: 14px;">public class SimpleJob implements
2.   
3. @Override
4. public void execute(JobExecutionContext context) throws
5. //获取jobDetail
6.         JobDetail jobDetail = context.getJobDetail();  
7.   
8. // 获取jobName
9.         String jobName = jobDetail.getName();  
10.   
11. //获取JobDataMap
12.         JobDataMap dataMap = jobDetail.getJobDataMap();  
13.           
14. //JobDataMap中获取用户传入的参数
15. int index = dataMap.getInt("index");  
16.           
17. //具体JOB要做的事
18. for(int i =0;i<index;i++){  
19. try
20. 1);  
21. catch
22.             }  
23. "simple job name:"+jobName+" ;turn "+i);  
24.         }  
25.   
26.     }  
27.   
28. }</span>



 



JobScheduler定时后台任务 android java定时任务job_spring



1. <span style="font-size: 14px;">public class
2.   
3. public static void
4.   
5. try
6. // 1、创建一个任务调度器
7.             Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();  
8.   
9. //2、创建一个作业
10. new JobDetail("simpleJob", Scheduler.DEFAULT_GROUP,  
11. class);  
12.   
13. // 2.1、JobDataMap里面加入需要的参数
14. "index", 5);  
15.   
16. //3、创建触发器,每8秒触发一次
17. 8);  
18. "simpleTrigger");  
19. //3.1、开始触发时间
20. new
21. // 4、把作业和触发器
22.             scheduler.scheduleJob(jobDetail, trigger);  
23.   
24. // 5、启动调度器
25.             scheduler.start();  
26.   
27. // 6、关闭调度器
28.             scheduler.shutdown();  
29.   
30. catch
31.             se.printStackTrace();  
32.         }  
33.     }  
34. }</span>



 

其中JobExecutionContext是quartz提供的一个上下文,从中可以获取job、trigger的信息;

 

quartz还有许多其他特性,例如job持久化、properties配置文件等,详细可参考最后的链接。

 

3、spring实现方式

 

spring对Java的Timer类和Quartz都提供了一个抽象层,使用我们可以更方便地使用它们。

 

1)spring对Timer的集成



JobScheduler定时后台任务 android java定时任务job_spring


1. <span style="font-size: 14px;"><?xml version="1.0" encoding="UTF-8"?>
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
5. default-autowire="byName">
6.   
7. <bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
8. <property name="scheduledTimerTasks">
9. <list>
10. <ref local="schedule" />
11. </list>
12. </property>
13. </bean>
14.   
15. <bean id="schedule" class="org.springframework.scheduling.timer.ScheduledTimerTask">
16. <property name="timerTask">
17. <ref bean="myTask" />
18. </property>
19. <property name="delay">
20. <value>1000</value>
21. </property>
22. <property name="period">
23. <value>1000</value>
24. </property>
25. </bean>
26.       
27. <bean id="myTask" class="com.test.MyTask" />
28.           
29. </beans></span>



 

2)spring对quartz的集成

 



JobScheduler定时后台任务 android java定时任务job_spring



    1. <span style="font-size: 14px;"><?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. "http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    4. "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
    5. default-autowire="byName">  
    6.   
    7. "myTask" class="com.test.MyTask"
    8.       
    9.     <!-- jobDetail -->  
    10. "quartzJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
    11. "targetObject" ref="myTask"
    12. "targetMethod" value="run"
    13. "concurrent" value="false"
    14.     </bean>  
    15.       
    16.     <!-- trigger -->  
    17. "quartzTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
    18. "jobDetail" ref="quartzJobDetail"
    19. "cronExpression" value="0/3 * * * * ?"/>  
    20.     </bean>  
    21.       
    22.     <!-- schdule -->  
    23. "quertzSchdule" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
    24. "triggers">  
    25.          <list>  
    26. "quartzTrigger"
    27.          </list>  
    28.       </property>  
    29.    </bean>  
    30.       
    31. </beans></span>


     

     在spring容器加载配置文件中的bean后,任务调度就会开始。