小議java中常用的定時任務

        每當我們想在項目中定期去執行或者重複執行某一個操作,定時這個字眼總會自覺不自覺的浮現在腦海裏。當我們並不熟悉任何定時器的時候,我們可能會選擇使用線程來完成這個工作:

<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中進行如下配置:

         第一步:啓動觸發器的配置開始-->設定每一個觸發器對應的觸發器

        

        第二步:調度的配置開始,設定每一個觸發器執行的頻率(由於使用的CronTrigger所以這裏我們使用的是克隆表達式)

   

       第三步:給三個不同的任務指定要執行的方法

   

        這樣,一旦quartz啓動,loadHomePageData的方法會以一個小時爲間隔重複執行;PS:第二步和第三步省略了另外兩個的配置;

        以上就是小編對項目中定時任務應用的理解和總結,純屬個人理解,如有問題或者好的建議,請留言給小編哦!!

                

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章