您的位置:首页 > 编程语言 > Java开发

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

2017-02-04 17:52 861 查看


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(), 1000, 2000);  

    }  

  

}</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后,任务调度就会开始。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: