定时器的实现,java定时器Timer和Quartz的介绍

我们可能经常遇到项目需要定时器,如果我们不了解定时器就会用线程去实现,例如:

package org.lzstone.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();  
        }  
   }  
} 

如果自己实现的定时器实现的不好,内存过多的话系统就会Over,所以处理定时执行或者重复执行的任务,定时器是很好的选择。

定时器我接触的主要是Timer和Quartz,下面就这两种我自己做个简单的介绍:

1.java中常见的定时器 
1)借助Java.util.Timer来实现 
2)OpenSymphony社区提供的Quartz来实现 
2.介绍Timer 
利用Timer开发定时任务是主要分为两个步骤: 
1)创建定时任务类 
示例代码:

package testIsValidLong;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;

public class TestTimer extends TimerTask {

	@Override
	public void run() {
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String time = sdf.format(date);
		System.out.println(time);
	}

}

2)运行定时任务,运行定时任务分为两种方式: 
2.1)程序直接启动 
示例代码: 

package testIsValidLong;

import java.util.Timer;

public class TestTimerMain {

	public static void main(String[] args) {
		Timer timer = new Timer();
		//new LzstoneTimeTask()- 所要安排的任务。
		//0- 执行任务前的延迟时间,单位是毫秒。
		//1*1000- 执行各后续任务之间的时间间隔,单位是毫秒。
		timer.schedule(new TestTimer(), 1000, 1*1000);
	}

}

2.2)web监听方式 
示例代码:

package org.lzstone.action
public class LzstoneMain implements ServletContextListener{
	private Timer timer = null;
	//初始化监听器,创建实例,执行任务
	public void contextInitialized(ServletContextEvent event){
		timer = new Timer();
		timer.schedule(new LzstoneTimeTask(),0,1*1000);
	}
	//销毁监听器,停止执行任务
	public void contextDestroyed(ServletContextEvent event){
		//注意,在此计时器调用的计时器任务的 run 方法内调用此方法,就可以绝对确保正在执行的任务是此计时器所执行的最后一个任务。
		timer.cancel();
	}
}

web.xml配置

<listener>  
   <listener-class>  
        org.lzstone.action.LzstoneMain  
   </listener-class>  
</listener>

3. 介绍Quartz 
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,可以用来创建简单或者复杂的定时任务,利用Quartz开发定时任务的步骤与Timer类似。 

利用Quartz开发定时任务是主要分为两个步骤: 
1)创建定时任务类 
示例代码:

package com.qlwb.job;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.qlwb.business.po.ClientUser2;
import com.qlwb.business.po.VipInvalid;
import com.qlwb.business.service.VipInvalidService;

/**
* @ClassName: VipInvalidJob  
* @Description: 加V失效定时任务
* @author: 
* @date 2018年5月31日  
 */
public class VipInvalidJob implements Job {
	
	private final Logger logger = Logger.getLogger(VipInvalidJob.class);
	
	private VipInvalidService service = new VipInvalidService();

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		try {
                定时业务...
		} catch (SQLException e) {
			logger.error("xxx出错");
			e.printStackTrace();
		} catch (ParseException e) {
			logger.error("xxx失败");
			e.printStackTrace();
		}
	}
	
}

2)运行定时任务,运行定时任务分为两种方式: 
2.1)程序直接启动,创建任务调度器及配置相应的任务计划 
示例代码:

package com.qlwb;

import java.text.ParseException;
import java.util.Date;

import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
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;

import com.aspire.boc.util.ResourceManager;
import com.qlwb.job.ActiveStartEndJob;
import com.qlwb.job.AdPositionPushReportJob;
import com.qlwb.job.HotCommentsNewsJob;
import com.qlwb.job.InformationFlowAdDealJob;
import com.qlwb.job.IntelligenceCommonDealJob;
import com.qlwb.job.IntelligenceSiteCarouselDealJob;
import com.qlwb.job.LifeAdvertStartEndJob;
import com.qlwb.job.LiveFlowSaveJob;
import com.qlwb.job.MsgInfoPushJob;
import com.qlwb.job.NewsAuditDelayJob;
import com.qlwb.job.NewsAuditStatisticsJob;
import com.qlwb.job.NewsCountAndViewsJob;
import com.qlwb.job.NewsPaperParserJob;
import com.qlwb.job.NoPayOrderDeal;
import com.qlwb.job.ProductStartEndJob;
import com.qlwb.job.PushNewsJob;
import com.qlwb.job.QlwbReporterJob;
import com.qlwb.job.QlydFlowRechargeJob;
import com.qlwb.job.QlydFlowRechargeResultJob;
import com.qlwb.job.RedMoneyPackageJob;
import com.qlwb.job.SmartCommunityCountJob;
import com.qlwb.job.VipInvalidJob;
import com.qlwb.job.YouliaoNewsPullJob;
import com.qlwb.job.mq.AddTicketReqCustomer;
import com.qlwb.job.mq.ClientUserGrapCustomer;
import com.qlwb.job.mq.EsDataStatusDealCustomer;
import com.qlwb.job.mq.GrapMoneyPackageConsumer;
import com.qlwb.job.mq.IntelligenceUserStatusPushCustomer;
import com.qlwb.job.mq.NewsListUpdateDealCustomer;
import com.qlwb.job.mq.PushMsgToAppCustomer;
import com.qlwb.job.mq.PushNewsCustomer;
import com.qlwb.job.mq.QlwbAddNewsRecordCustomer;
import com.qlwb.job.mq.QlydAddPicWaterCustomer;
import com.qlwb.job.mq.QlydAutoNewsCommentCustomer;
import com.qlwb.job.mq.TransVideoCodeCustomer;
import com.qlwb.job.mq.UserCreditsOptCustomer;
import com.qlwb.job.mq.UserFeedBackPushCustomer;
import com.qlwb.job.mq.VideoTranscodingCustomer;
import com.qlwb.job.mq.ViewCountIncrCustomer;
import com.qlwb.thread.AdPositionTread;
import com.qlwb.thread.AppOpenImgThread;
import com.qlwb.thread.AuditNewsAssignThread;
import com.qlwb.thread.DealGrabPackageThread;

public class MainEntry {

	private static final Logger logger = Logger.getLogger(MainEntry.class);

	public static void main(String args[]) {

		ResourceManager rm = ResourceManager.getInstance();
		AppOpenImgThread appOpenImgThread = new AppOpenImgThread();
		appOpenImgThread.start();
		
		SchedulerFactory schedFact = new StdSchedulerFactory();
		try {
			Scheduler Sched = schedFact.getScheduler();
			String[] jobs = Sched.getJobNames(Scheduler.DEFAULT_GROUP);
			if (jobs.length == 0) {
				//用户vip失效
				JobDetail vipInvalidDetail = new JobDetail(
						"vipInvalidJob", Scheduler.DEFAULT_GROUP,
						VipInvalidJob.class);
				Trigger vipInvalidTrigger = null;
				if (!"-".equals(rm.getValue("Timer.vipInvalidTrigger"))) {
					vipInvalidTrigger = new CronTrigger(
							"vipInvalidJob", Scheduler.DEFAULT_GROUP,
							rm.getValue("Timer.vipInvalidTrigger"));
				}
				if (vipInvalidTrigger != null) {
					Sched.scheduleJob(vipInvalidDetail,
							vipInvalidTrigger);
				}
			}

			Sched.start();
		} catch (SchedulerException e) {
			logger.error(
					"InitQuartzJob.main SchedulerException:" + e.getMessage(),
					e);
		} catch (ParseException e) {
			logger.error("InitQuartzJob.main ParseException:" + e.getMessage(),
					e);
		} catch (Exception e) {
			logger.error("InitQuartzJob.main Exception:" + e.getMessage(), e);
		}
	}
}

2.2)web监听方式 
示例代码: 

package org.lzstone.action  
public class LzstoneMainListener implements ServletContextListener{  
       private Timer timer = null;  
       //初始化监听器,创建实例,执行任务  
       public void contextInitialized(ServletContextEvent event){  
               LzstoneMain.run();  
       }  
       //销毁监听器,停止执行任务  
       public void contextDestroyed(ServletContextEvent event){  
              LzstoneMain.stop();  
        }  
}

web.xml配置

<listener>  
   <listener-class>  
        org.lzstone.action.LzstoneMainListener  
   </listener-class>  
</listener>

4.对比 
Timer方式实现定时器,原理简单,实现方便,在执行简单的任务比较方便,不足之处是无法确定执行时间,并且依赖性比较强,必须继承指定的类 
Quartz方式实现定时器,方便,清晰指定启动时间,定时参数比较灵活,容易实现比较复杂的定时任务,不足之处是需要实现特定接口,加载其框架 
两种方式各有优缺点,在特定场合可以根据其特点选择使用。

猜你喜欢

转载自blog.csdn.net/lipr86/article/details/83088933