1. 程式人生 > >Java之幾種定時器的使用

Java之幾種定時器的使用

沒有去仔細研究這兩種定時器的API,會使用及能在專案中應用即可;

import org.quartz.CronExpression;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

一、JobDetail的用法

public void startTasl(ServletContext context, String jobName, String jobGroup,
         SInterfacePara sInterP, String cexpReg) throws ParseException, SchedulerException {

 //建立一個jobDetail物件=>jobName:自定義工作名稱;jobGroup自定義工作組名稱;啟動的類(須實現Job介面)
        JobDetail jobDetail = new JobDetail(jobName, jobGroup, SimpleJob.class);

//將所需物件引數放在此Map集合中,後續使用可取出(map.get("key"))
        jobDetail.getJobDataMap().put("key", key);

//將servletContext 放置在Map中;
        jobDetail.getJobDataMap().put("context", context);

//建立一對觸發器物件;
        CronTrigger cronTrigger = new CronTrigger("trigger" + jobName, "tgroup" + jobName);

 //建立定時任務表示式,將表示式寫入其中(此表示式的書寫格式,最下面會有詳細介紹);
        CronExpression cexp = new CronExpression("表示式");// ①-2:定義Cron表示式
        cronTrigger.setCronExpression(cexp);// ①-3:設定Cron表示式
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        scheduler.scheduleJob(jobDetail, cronTrigger);
        scheduler.start();

    }

二、實現 StatefulJob 介面

import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

 public static void addJob(Task task,ServletContext context) throws SchedulerException, ParseException, InstantiationException, IllegalAccessException, ClassNotFoundException {
           Scheduler sched = sf.getScheduler();
           Job imp = (Job) Class.forName(task.getClassname()).newInstance();//具體的哪個類
           JobDetail jobDetail = new JobDetail(task.getId(), JOB_GROUP_NAME, imp.getClass());//任務名,任務組,任務執行類
           jobDetail.getJobDataMap().put("ServletContext", context);
           //觸發器
           Trigger trigger = null;
           if(task.getType()==1){
              trigger = getSimpleTrigger(task);
           }else{
              trigger = getCronTrigger(task);
           }
           sched.scheduleJob(jobDetail,trigger);
           //啟動
           if(!sched.isShutdown()){
              sched.start();
           }
       }

public static Trigger getSimpleTrigger(Task task){
        SimpleTrigger trigger = new SimpleTrigger(task.getId(),JOB_GROUP_NAME);
        if(!(task.getStartTime().trim().equals(""))){
            trigger.setStartTime(parseDateString(task.getStartTime()));
        }else{
            trigger.setStartTime(new Date());
        }
        if(!(task.getEndTime().trim().equals(""))){
            trigger.setEndTime(parseDateString(task.getEndTime()));
        }
        if(task.getRepeatCount().equals("-1")){
            trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
        }else{
            trigger.setRepeatCount(Integer.parseInt(task.getRepeatCount()));
        }
        trigger.setRepeatInterval(Long.parseLong(task.getRepeatInterval())*1000L);
        return trigger;
    }
  
    public static Trigger getCronTrigger(Task task){
        CronTrigger trigger =  new CronTrigger(task.getId(), TRIGGER_GROUP_NAME);//觸發器名,觸發器組
        try {
            trigger.setCronExpression(task.getContent());
        } catch (ParseException e) {
            e.printStackTrace();
        }//觸發器時間設定
        return trigger;
    }

定時的那個類要實現StatefulJob介面

三、執行緒(自個編寫一個執行緒,在web.xml中啟動時優先),下面有個案例,可套用;

1、web.xml新增配置

  <servlet-name>MyServlet</servlet-name>  
     <servlet-class>my.person.engine.quartz.MyServlet</servlet-class>  
     <load-on-startup>0</load-on-startup>
  </servlet>  
 
  <servlet-mapping>  
     <servlet-name>MyServlet</servlet-name>  
     <url-pattern>/</url-pattern>  
  </servlet-mapping> 

2、編寫一個servlet 繼承HttpServlet, 初如化時去啟動執行緒

public void init(ServletConfig config) throws ServletException {
        super.init(config);
        logger.info("初始化了嗎");
        try {
            TestSubmit submit = new TestSubmit ();
            submit.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

public class TestSubmit  extends Thread {

public void run() {

     //利用while迴圈不斷的執行;

          程式碼塊    注:如果這裡執行週期,必須保證執行緒不會起衝突,否則可能引起資料錯誤;

    }

}

四、在監聽中註冊定時,繼承TimerTask;

1、先在web.xml中進行註冊;

<listener id="Listener_3">
        <listener-class>
            pde.ams.MobileContextListener
        </listener-class>
    </listener>   

2、繼承上下文監聽

public class MobileContextListener implements ServletContextListener {
    private static Logger logger = Logger.getLogger(MobileContextListener.class);
    private Timer timer = null;
    
    public void contextDestroyed(ServletContextEvent arg0) {
        timer.cancel();    
        ProxoolFacade.shutdown();    //連線池關閉
    }

    public void contextInitialized(ServletContextEvent arg0){
        timer = new Timer(true);                        //定時器已啟動        
//        long delay = 5*1000;                            //5秒後執行
        long delay = 0;
//        long interval = 5*1000 ;                    //定時為 每5秒執行一次定時
        long interval=13*1000;//實時傳送
        try {
            timer.schedule(new DaiBanSendTaskJob(arg0.getServletContext()), delay, interval);//已經將全文索引新增任務排程表
        } catch (Exception e) {
            timer.cancel();    
        }    
    }
}

3、繼承TimerTask 類

public class DaiBanSendTaskJob extends TimerTask {

public void run() {