每当我们想在项目中定期去执行或者重复执行某一个操作,定时这个字眼总会自觉不自觉的浮现在脑海里。当我们并不熟悉任何定时器的时候,我们可能会选择使用线程来完成这个工作:

<span style="font-size:18px;">package org.ysc.action
public class FinanceAction extends Thread{
       private Date date;
       public void run{
       try{
       while(true){
       Thread.sleep((int)(Math.random()*1000));
       date = new Date();
       //定时执行任务
       }
       }catch(Exception e){
        e.printStackTrace();
       }
}
}</span>


        但是如果我们的定时器实现不好,将会使定时器占用系统中的过多内存,给系统造成性能问题,所以在执行定时或者重复的任务,线程并不是最好的选择;

     java中常用的定时器

      1).使用java.util.Timer 来实现

       2).Quartz这个开源的调度框架

➷  Timer的具体实现

           使用Timer定义一个定时任务主要分为两个步骤:

      1.   创建定时任务类:

<span style="font-size:18px;">package org.ysc.action
import java.util.TimeTask
public class MyTimeTask extends TimeTask{
       public void run(){
              //要执行的定时任务
       }
}</span>

  2.  运行定时任务:

2.1   程序直接启动

<span style="font-size:18px;">package org.ysc.action
public class Testmain{
       .......
       public void run(){
        //执行定时器的任务
        //创建实例
        Timer timer = new Timer();
        参数:
        new MyTimeTask()- 所要安排的任务。
        0- 执行任务前的延迟时间,单位是毫秒。
        1*1000- 执行各后续任务之间的时间间隔,单位是毫秒。
        timer.schedule(new MyTimeTask(),0,1*1000);
       }
}</span>

2.2  web监听的方式

web.xml的配置

<span style="font-size:18px;"><listener>
   <listener-class>
        org.ysc.action.Testmain
   </listener-class>
</listener></span> 
 具体实现代码:
<span style="font-size:18px;">package org.ysc.action
public class Testmain implements ServletContextListener{
       private Timer timer = null;
       //初始化监听器,创建实例,执行任务
       public void contextInitialized(ServletContextEvent event){
               timer = new Timer();
               timer.schedule(new MyTimeTask(),0,1*1000);
       }
       //销毁监听器,停止执行任务
       public void contextDestroyed(ServletContextEvent event){
              //注意,在此计时器调用的计时器任务的 run 方法内调用此方法,就可以绝对确保正在执行的任务是此计时器所执行的最后一个任务。
              timer.cancel();
        }
}</span>

➷  Quartz 的具体实现

1. 程序直接启动,创建任务调度的方式

<span style="font-size:18px;">package org.yscTest.action
public class TestMain{
       private static Scheduler sched;
       public static void run() throws Exception{
              //创建LzstoneTimeTask的定时任务
              JobDetail jobDetail = new JobDetail("MyJob",sched.DEFAULT_GROUP,MyTimeTask.class);
              //目标 创建任务计划,且定义执行时间为 每天中午的12点执行该定时任务
              CronTrigger trigger = new CronTrigger("MyTrigger","myTrigger","0 0 12 * * ?");
        
              sched = new org.quartz.impl.StdSchedulerFactory().getScheduler();
			  //将当前定义的job和触发器添加到任务调度器中进行管理
              sched.scheduleJob(jobDetail,trigger);
			  //启动任务调度器
              sched.start();
       }
       //停止任务调度
       public static void stop() throws Exception{
              sched.shutdown();
        }
}
//执行
public class Main{
       .............
       public void run(){
            TestMain.run();
       }
       ............
}</span>

 2.web的监听方式 

<span style="font-size:18px;">package org.ysc.action
public class TestMainListener implements ServletContextListener{
       private Timer timer = null;
       //初始化监听器,创建实例,执行任务
       public void contextInitialized(ServletContextEvent event){
               TestMain.run();
       }
       //销毁监听器,停止执行任务
       public void contextDestroyed(ServletContextEvent event){
              TestMain.stop();
        }
}</span>

web.xml的配置:

<span style="font-size:18px;"><listener>
   <listener-class>
        org.ysc.action.TestMainListener
   </listener-class>
</listener></span>

3.Timer 和Quartz的对比:

         Timer的定时器,原理简单,实现方便,上手容易;但是我们无法使用确切的时间(比如某天某点五十),并且我们要使用TImer必须继承指定的类,所以依赖性较强;

          Quartz定时器,方便,在日期的设定上更加灵活方便,可以实现比较复杂的定时任务,但是我们需要实现指定的接口,必须引入指定的jar包;

    两者的关系:

        Quartz中有两种触发器,SimpleTrigger和CronTrigger,小编感觉:但从实现的方式和实现的效果来看,Timer和Quartz中的SimpleTrigger中是类似的,只是设定时长和间隔次数;

        综上所述,两者各有各的优点,项目中的使用可以结合具体情况和定时的特点来选择这两种定时器;

➷   扩展--spring的“”定时任务“

      当提起spring时,我们第一反应都是它的IOC容器和aop日志,但是很少想起spring对定时任务的支持;下面小编就将spring中对Timer和Quartz的支持一一道来:

      1.对Timer的支持

        ♚   创建定时任务类:

<span style="font-size:18px;">package org.test.action
import java.util.TimeTask
public class MyTimeTask extends TimeTask{
       public void run(){
              //执行的定时器任务
       }
}</span>

      ♚   配置applicationContext.xml文件:

<span style="font-size:18px;"><!--注册定时执行任务实体-->
<bean id="lzstoneTimeTask" class="org.test.action.MyTimeTask3"/>
<!--注册定时器信息-->
<bean id="taskInfo" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<!--第一次执行任务前需要等待的时间,这里设置为3秒-->
<property name="delay">
<value>3000</value>
</property>
<!--设置任务的执行周期 这里设置为4秒-->
<property name="period">
  <value>4000</value>
</property>
<!--设置具体执行的任务 这里设置为MyTimeTask3-->
<property name="timerTask">
<ref local="MyTimeTask3"/>
</property>
</bean>
<!--配置定时器任务的调度器-->
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<!--注册定时器列表-->
<property name="scheduledTimerTasks">
    <list>
        <ref local="taskInfo"/>
        ........
    </list>
</property>
</bean></span>

       ♚  web项目中的启动设置

<span style="font-size:18px;"><context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
 <listener-class>
		  org.springframework.web.context.ContextLoaderListener
 </listener-class>
</listener></span>

   2. 对Quartz的支持

         ♚  创建定时任务类:

<span style="font-size:18px;">package org.test.action
public class MyQuartzTask{
       public void execute(){
              //执行的定时器任务
       }
}</span>


       ♚  在applicationContext.xml中进行配置:

<span style="font-size:18px;"><!--注册定时执行任务实体-->
<bean id="MyQuartzTask" class="org.test.action.MyQuartzTask"/>
<!--注册定时器信息-->
<bean id="taskInfo" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!--指定要执行的定时任务类  这里是LzstoneQuartzTask-->
	<property name="targetObject">
		<ref local="MyQuartzTask"/>
	</property>
<!--指定定时器任务类要执行的方法名称 这里是execute-->
	<property name="targetMethod">
		<value>execute</value>
	</property>
</bean>
<!--配置定时器任务的调度器-->
<bean id="quartzTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<!--声明要运行的实体-->
	<property name="jobDetail">
		<ref local="taskInfo"/>
	</property>
<!--设置运行时间-->
	<property name="cronExpression">
		<value>0 0 12 * * ?</value>
	</property>
</bean>
<!--注册监听器-->
<bean id="registerQuartz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!--注册定时器实体 集合-->
	<property name="triggers">
		<list>
			  <ref local="quartzTrigger"/>
		</list>
	</property>
</bean></span>


      如果我们需要使用Quartz框架来对既有程序中某个方法进行定期执行,可以使用以下的配置(以定时执行loadHomePageData方法为例):

       首先,我们引入quartz的包和指定的版本;

        然后在ApplicationContext.xml中进行如下配置:

         第一步:启动触发器的配置开始-->设定每一个触发器对应的触发器

        

开启定时任务 只执行一次java java定时任务怎么触发_多线程

第二步:调度的配置开始,设定每一个触发器执行的频率(由于使用的CronTrigger所以这里我们使用的是克隆表达式)

   

开启定时任务 只执行一次java java定时任务怎么触发_定时任务_02

       第三步:给三个不同的任务指定要执行的方法

   

开启定时任务 只执行一次java java定时任务怎么触发_spring_03

        这样,一旦quartz启动,loadHomePageData的方法会以一个小时为间隔重复执行;PS:第二步和第三步省略了另外两个的配置;

        以上就是小编对项目中定时任务应用的理解和总结,纯属个人理解,如有问题或者好的建议,请留言给小编哦!!

                

开启定时任务 只执行一次java java定时任务怎么触发_quartz_04