Java 定时任务的几种实现方式总结

java定时任务主要有以下几种实现方式:

(1)JDK 自带的定时器实现

(2)Quartz 定时器实现

(3)Spring 相关的任务调度

1、JDK自带的java.util.Timer 来实现
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;


public class Test {
	/**
	 *  第一种方法:设定指定任务task在指定时间执行,只执行一次  
	 *  schedule(TimerTask task, Date time)  
	 */
    public static void timer1() {  
        Timer timer = new Timer();  
        timer.schedule(new TimerTask() {  
            public void run() {  
                System.out.println(new Date() +"\t"+"---指定要执行任务---");  
            }  
        },  new Date(System.currentTimeMillis() + 2000)); 
    }  
    
    /**
     *  第二种方法:设定指定任务task在延迟delay执行,只执行一次    
     *  schedule(TimerTask task, long delay)   
     *  delay单位毫秒
     */
    public static void timer2(){
    	Timer timer = new Timer();  
        timer.schedule(new TimerTask() {  
            public void run() {  
            	System.out.println(new Date() +"\t"+"---指定要执行任务---");  
            }  
        }, 2000);  
    }
    
    /**
     *  第三种方法:设定指定任务task在指定延迟delay后进行周期性执行,周期时间为period  
     *  schedule(TimerTask task, long delay, long period) 
     *  scheduleAtFixedRate(TimerTask task, long delay, long period)  
     *  delay,period 单位为毫秒
     */
    public static void timer3() {  
        Timer timer = new Timer();  
        timer.schedule(new TimerTask() {  
            public void run() {  
            	System.out.println(new Date() +"\t"+"---指定要执行任务---");  
            }  
        }, 1000, 1000);  
    }  
    /**
     *  第四种方法:设定指定的任务task在指定的时间firstTime开始进行重复的周期性执行,周期时间为period
     *  schedule(TimerTask task, Date firstTime, long period) 
     *  scheduleAtFixedRate(TimerTask task,Date firstTime,long period)
     *  period 单位为毫秒
     */
    public static void timer4() {  
        Calendar calendar = Calendar.getInstance();  
        calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制时  
        calendar.set(Calendar.MINUTE, 0);       // 控制分  
        calendar.set(Calendar.SECOND, 0);       // 控制秒  
  
        Date time = calendar.getTime();         // 得出执行任务的时间,此处为今天的12:00:00  
        Timer timer = new Timer();  
        timer.schedule(new TimerTask() {  
            public void run() {  
            	System.out.println(new Date() +"\t"+"---指定要执行任务---");  
            }  
        }, time, 1000);
    }  
    
    /**
     * schedule和scheduleAtFixedRate方法的区别:
     * (1)schedule方法:如果第一次执行时间被delay了,随后的执行时间按照上一次实际执行完成的时间点进行计算,即:下一次的执行时间点=上一次程序执行完成的时间点+间隔时间 
     * (2)scheduleAtFixedRate方法:如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,即:下一次的执行时间点=上一次程序开始执行的时间点+间隔时间,
     * 并且前一个任务的执行时间大于间隔时间,就会与当前任务重叠,TimerTask中的执行体需要考虑线程同步 
     */
    
}

Timer的缺陷:

(1)由于执行任务的线程只有一个,所以如果某个任务的执行时间过长,那么将破坏其他任务的定时精确性。如一个任务每1秒执行一次,而另一个任务执行一次需要5秒,那么如果是固定速率的任务,那么会在5秒这个任务执行完成后连续执行5次,而固定延迟的任务将丢失4次执行。

(2)如果执行某个任务过程中抛出了异常,那么执行线程将会终止,导致Timer中的其他任务也不能再执行。

(3)Timer使用的是绝对时间,即是某个时间点,所以它执行依赖系统的时间,如果系统时间修改了的话,将导致任务可能不会被执行。

由于Timer存在上面说的这些缺陷,在JDK1.5中,我们可以使用ScheduledThreadPoolExecutor来代替它,使用Executors.newScheduledThreadPool工厂方法或使用ScheduledThreadPoolExecutor的构造函数来创建定时任务,它是基于线程池的实现,不会存在Timer存在的上述问题,当线程数量为1时,它相当于Timer。

2、JDK自带的ScheduledThreadPoolExecutor来实现
 /**
     * ScheduledThreadPoolExecutor 有两种创建方式:第一种,通过Executors创建;第二种:通过构造方法
     * scheduleAtFixedRate(Runnable command, long initialDelay, long period,TimeUnit unit)
     * initialDelay 首次执行任务的延迟时间
     * period  每次执行任务的间隔时间
     * unit   执行的时间间隔数值单位
     * 间隔单位毫秒:TimeUnit.MILLISECONDS 
     * 间隔单位秒:TimeUnit.SECONDS 
     * 间隔单位分钟:TimeUnit.MINUTES 
     * 间隔单位小时:TimeUnit.HOURS 
     * 间隔单位天:TimeUnit.DAYS
     */
    public static void timer5(){
    	ScheduledThreadPoolExecutor scheduled = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(10);
//    	ScheduledThreadPoolExecutor  scheduled = new ScheduledThreadPoolExecutor(10);
    	scheduled.scheduleAtFixedRate(new Runnable() {
             @Override
             public void run() {
                 System.out.println(new Date());
             }
         }, 0, 40, TimeUnit.MILLISECONDS);
    }
3、Quartz整合spring实现

(1)增加maven依赖


   org.springframework
   spring-web
   3.2.9.RELEASE	


   org.quartz-scheduler
   quartz
   1.8.5

(2)增加定时业务类

package quartz;

import java.util.Date;

import javax.annotation.PostConstruct;

import org.springframework.stereotype.Service;

@Service("ExpireJobTaskService")
public class ExpireJobTask {
	
	public void reload() {
		load();
	}
	
	@PostConstruct
	public void load(){
		System.out.println(new Date()+"\t"+"执行定时任务");
	}

}

(3)增加spring配置



 
	
	
	
	
	
	
	
		
		
	
	
	
		
		
	 
	
	
	
		
			
				
			
		
	
	
	
4、spring定时任务实现:

spring定时任务比较简单,只需要在maven依赖中引入相关jar包,使用注解进行配置。

示例:

package quartz;

import java.util.Date;

import javax.annotation.PostConstruct;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class ExpireJobTask {
	
	@PostConstruct
	public void reload() {
		load();
	}
	
	@Scheduled(cron = "0 0/1 0 * * ?")
	public void load(){
		System.out.println(new Date()+"\t"+"执行定时任务");
	}

}







你可能感兴趣的:(Java 定时任务的几种实现方式总结)