Java 定时任务总结一

 Java定时任务总结
 
 一.从技术上分类大概分为以下三种方式:
 
 1.Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务;
   说明:
    java.util.Timer定时器,实际上是个线程,定时执行TimerTask类
    一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内,TimerTask一般是以匿名类的方式创建。
 
 2.Java可以实现Runnable接口,这里不讲解,以后陆续补充;
   
 
 3.Spring3.0以后自带的task,可以看做一个轻量级的Quartz,它的实现方式如下:
   (1).Spring3.0 自带的作业调度(quartz)的两种业务处理方式
        a.org.springframework.scheduling.quartz.JobDetailFactoryBean
        b.org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
        说明:Spring通过JobDetailBean/JobDetailFactoryBean,MethodInvokingJobDetailBean/MethodInvokingJobDetailFactoryBean实现Job的定义。
     后者更加实用,只需指定要运行的类,和该类中要运行的方法即可,Spring将自动生成符合Quartz要求的JobDetail
    
   (2).Spring3.0 自带的作业调度(quartz)的两种触发方式:
         a. org.springframework.scheduling.quartz.SimpleTriggerBean  触发器  每隔多长时间运行一次 比如:每隔10分钟运行一次
         b. org.springframework.scheduling.quartz.CronTriggerBean    调度器  每到指定时间则触发一次  比如:每天12:00运行一次
  
   (3).配置调度任务,开启调度
       org.springframework.scheduling.quartz.SchedulerFactoryBean
      
二.具体操作实现:

1.java.util.Timer :
    一些基本方法的说明:
    Timer timer = new Timer(true);
 // true 说明这个timer以daemon方式运行(优先级低,
 // 程序结束timer也自动结束),注意,javax.swing
 // 包中也有一个Timer类,如果import中用到swing包,
 // 要注意名字的冲突。

 TimerTask task = new TimerTask() {
  public void run() {
   // 每次需要执行的代码放到这里面。
  }
 };

 // 以下是几种调度task的方法:

 //timer.schedule(task, time);
 // time为Date类型:在指定时间频度执行一次。

 //timer.schedule(task, firstTime, period);
 // firstTime为Date类型,period为long
 // 从firstTime时刻开始,每隔period毫秒执行一次。

 //timer.schedule(task, delay);
 // delay 为long类型:从现在起过delay毫秒执行一次

 //timer.schedule(task, delay, period);
 // delay为long,period为long:从现在起过delay毫秒以后,每隔period
 // 毫秒执行一次。

 

package com.TimerWay.Timer;

import java.util.TimerTask;

public class TimerTaskJunit extends TimerTask {

	@Override
	public void run() {
		System.out.println("TimerTask1=========");
	}

}

 

package com.TimerWay.Timer;

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


public class Test {
	
	/**
	 * 从现在起过1000毫秒以后,每隔2000毫秒,执行一次TimerTaskJunit的Run方法
	 */
	public void test1(){
		Timer timer = new Timer();  
		timer.schedule(new TimerTaskJunit(), 1000, 2000);  
	}
	
	/**
	 * 每天中午11:00:00 执行定时任务,如果当前时间超过了11点,就明天执行11点执行任务
	 */
	public void test2(){
		final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long period = 1000 * 60 * 24;//间隔执行时间  24分钟
		Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Date now = new Date();
                System.out.println(sdf.format(now)+"\t helloworld");
            }
        },DateUtil.timeInMillis(), period);
	}
	
	public static void main(String[] args) {
		Test t = new Test();
		t.test1();
		//t.test2();
		
	}
}

 2.Spring3.0 自带的Quartz

    a.org.springframework.scheduling.quartz.JobDetailFactoryBean

   

<bean name="productDetail" class="com.TimerWay.quartz2.ProductDetail"/>


<bean name="runJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
		<property name="jobClass" value="com.TimerWay.quartz2.RunJob" />
		
		<!-- 属性注入  任务执行时 ,将属性注入到 jobClass对应Value类的属性 -->
		<property name="jobDataAsMap">
			<map>
				<entry key="productDetail" value-ref="productDetail" />
			</map>
		</property>
	</bean>



<!-- Simple Trigger, run every 5 seconds first trigger -->
	<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
		<!-- 任务 -->
		<property name="jobDetail" ref="runJob" />
		<!-- 频度  每10分钟做一次任务 -->
		<property name="repeatInterval" value="600000" />
		<!-- 待延迟之后,开始工作 -->
		<property name="startDelay" value="1000" />
	</bean>


<!-- 配置调度,启动调度任务 -->
	<bean id="schdulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="jobDetails">
			<list>
				<ref bean="runMeJob" />
			</list>
		</property>
		<property name="triggers">
			<list>
				<ref bean="simpleTrigger" />
			</list>
		</property>
		<!-- 
		<property name="triggers">
			<list>
				<ref bean="cronTrigger" />
			</list>
		</property>
		 -->
		
	</bean>

 

package com.TimerWay.quartz2;

import org.apache.log4j.Logger;


/**
 * 更新商城发货单的状态
 * @author daizhao
 *
 */
public class ProductDetail {
	
	private final static Logger log = Logger.getLogger(ProductDetail.class);
	
	public void product(){
		
		log.info("生产。。。。");
	}
}

 

说明:在这里我用的触发器是org.springframework.scheduling.quartz.SimpleTriggerFactoryBean,也可用

org.springframework.scheduling.quartz.CronTriggerFactoryBean,下面的例子,采用。

   b.org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean

  

<bean name="productDetail" class="com.TimerWay.quartz2.ProductDetail"/>
<!-- 会自动的生成JobDetailFactoryBean -->
	<bean id="runMeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactor yBean">
		<!-- 要执行业务的Bean  --> 
		<property name="targetObject" ref="productDetail" /> 
		<!-- 执行业务的方法  -->
		<property name="targetMethod" value="product" /> 
	</bean> 

<!--Cron Trigger, run every 5 seconds  second trigger  类似Unix中的Crontab的脚步机制-->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
	<!-- 任务 -->
	<property name="jobDetail" ref="runJob" />
	<!-- 频度 -->
	<property name="cronExpression" value="0/5 * * * * ?" />
	</bean>

<!-- 配置调度,启动调度任务 -->
	<bean id="schdulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="jobDetails">
			<list>
				<ref bean="runMeJob" />
			</list>
		</property>
		<property name="triggers">
			<list>
				<ref bean="cronTrigger" />
			</list>
		</property>		
	</bean>

 说明:我解释一些,为什么我用这个JobDetailBean/JobDetailFactoryBean,MethodInvokingJobDetailBean/MethodInvokingJobDetailFactoryBean实现Job的定义,因为,有的时候,开发时,会遇到Spring自带的Quartz和Quartz包冲突的问题,异常如下:

 

Caused by: java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.JobDetailBean has interface org.quartz.JobDetail as super class
 
Caused by: java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class
 
Caused by: java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.SimpleTrigger has interface org.quartz.SimpleTrigger as super class

所以,解决方式如下:

 

1.降低Quartz版本,降到1.X去。
2.升级Spring版本到3.1+,根据Spring的建议,将原来的**TriggerBean替换成**TriggerFactoryBean,例如CronTriggerBean 就可以替换成 CronTriggerFactoryBean,  SimpleTriggerBean可以替换成SimpleTriggerFactoryBean, JobDetailBean可以替换成 JobDetailFactoryBean
替换之后问题解决。

我后续,还会补充,Spring的注解定时任务和JavaRunnable定时任务,今天先到这里

你可能感兴趣的:(java,spring,timer,quartz,timertask)