java作业调度、定时任务实践(三种实现方式)

    xiaoxiao2021-03-26  19

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

    博客分类:  java 作业调度  

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

     

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

     

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

     

    1、Timer的实现方式

     

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

     

    Java代码   <span style="font-size: 14px;">public class MyTask extends TimerTask{          @Override       public void run() {           System.out.println("execute my task!");       }      }</span>  

     

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

     

    Java代码   <span style="font-size: 14px;">public class MyTimer {              public static void main(String[] args) {           Timer timer= new Timer();            // 1秒钟后开始第一次,以后每隔2秒执行一次           timer.schedule(new MyTask(), 10002000);       }      }</span>  

     

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

     

    原理:

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

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

     

     

     2、quartz实现方式

     

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

     

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

    1)job,相当于timer的task;

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

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

     

    下面是一个简单例子:

     

    Java代码   <span style="font-size: 14px;">public class SimpleJob implements Job {          @Override       public void execute(JobExecutionContext context) throws JobExecutionException {           //获取jobDetail           JobDetail jobDetail = context.getJobDetail();              // 获取jobName           String jobName = jobDetail.getName();              //获取JobDataMap           JobDataMap dataMap = jobDetail.getJobDataMap();                      //JobDataMap中获取用户传入的参数           int index = dataMap.getInt("index");                      //具体JOB要做的事           for(int i =0;i<index;i++){               try {                   TimeUnit.SECONDS.sleep(1);               } catch (InterruptedException e) {               }               System.out.println("simple job name:"+jobName+" ;turn "+i);           }          }      }</span>  

     

    Java代码   <span style="font-size: 14px;">public class QuartzTest {          public static void main(String[] args) {              try {               // 1、创建一个任务调度器               Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();                  //2、创建一个作业               JobDetail jobDetail = new JobDetail("simpleJob", Scheduler.DEFAULT_GROUP,                       SimpleJob.class);                  // 2.1、JobDataMap里面加入需要的参数               jobDetail.getJobDataMap().put("index"5);                  //3、创建触发器,每8秒触发一次               Trigger trigger = TriggerUtils.makeSecondlyTrigger(8);               trigger.setName("simpleTrigger");               //3.1、开始触发时间               trigger.setStartTime(new Date());               // 4、把作业和触发器               scheduler.scheduleJob(jobDetail, trigger);                  // 5、启动调度器               scheduler.start();                  // 6、关闭调度器               scheduler.shutdown();              } catch (SchedulerException se) {               se.printStackTrace();           }       }   }</span>  

     

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

     

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

     

    3、spring实现方式

     

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

     

    1)spring对Timer的集成

    Xml代码   <span style="font-size: 14px;"><?xml version="1.0" encoding="UTF-8"?>   <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"       default-autowire="byName">          <bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">           <property name="scheduledTimerTasks">               <list>                   <ref local="schedule" />               </list>           </property>       </bean>          <bean id="schedule" class="org.springframework.scheduling.timer.ScheduledTimerTask">           <property name="timerTask">               <ref bean="myTask" />           </property>           <property name="delay">               <value>1000</value>           </property>           <property name="period">               <value>1000</value>           </property>       </bean>              <bean id="myTask" class="com.test.MyTask" />              </beans></span>  

     

    2)spring对quartz的集成

     

    Java代码   <span style="font-size: 14px;"><?xml version="1.0" encoding="UTF-8"?>   <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"       default-autowire="byName">          <bean id="myTask" class="com.test.MyTask" />              <!-- jobDetail -->       <bean id="quartzJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">           <property name="targetObject" ref="myTask" />           <property name="targetMethod" value="run" />           <property name="concurrent" value="false" />       </bean>              <!-- trigger -->       <bean id="quartzTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">           <property name="jobDetail" ref="quartzJobDetail" />           <property name="cronExpression" value="0/3 * * * * ?"/>       </bean>              <!-- schdule -->       <bean id="quertzSchdule" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">         <property name="triggers">            <list>               <ref bean="quartzTrigger" />            </list>         </property>      </bean>          </beans></span>  

     

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

    转载请注明原文地址: https://ju.6miu.com/read-658301.html

    最新回复(0)