Javaタイミングタスクのいくつかの実装方法のまとめ

7214 ワード

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つしかないため,あるタスクの実行時間が長すぎると,他のタスクのタイミング精度が損なわれる.1つのタスクが1秒ごとに実行され、別のタスクが1回実行されるのに5秒かかる場合、固定レートのタスクであれば、5秒でこのタスクの実行が完了した後に5回連続して実行され、固定遅延のタスクでは4回の実行が失われます.
(2)あるタスクの実行中に例外が投げ出された場合、実行スレッドは終了し、Timer内の他のタスクも実行できなくなる.
(3)Timerは絶対時間,すなわちある時点を用いているので,システムに依存する時間を実行し,システム時間が変更されるとタスクが実行されない可能性がある.
Timerには前述の欠陥が存在するため、JDK 1である.5では、代わりにScheduledThreadPoolExecutorを使用してExecutorsを使用することができます.新w S h e d u l edThreadPoolファクトリメソッドまたはS h e d u l edThreadPoolExecutorのコンストラクション関数を使用して、スレッドプールの実装に基づいて、スレッド数が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"+"      ");
	}

}