歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

在Java中使用定時任務的最佳實踐

之前大部分人在遇到需要使用定時任務的時候首先會想到Timer類,用法一般就是:

new Timer("timer").schedule(new TimerTask() { 
            @Override 
            public void run() { 
                System.out.println("執行任務"); 
            } 
        }, 1000L, 1000L);

不過在JDK5.0之後就不建議使用這個Timer了,因為它有很多的缺陷。

在新的java.util.concurrent包中的ScheduledExecutorService可以替代這個Timer:

使用方法舉例:

ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1); 
 exec.scheduleAtFixedRate(new Runnable() { 
    public void run() { 
    try{ 
        throw new RuntimeException(); 
    }catch (Exception e){ 
        System.out.println("RuntimeException catched"); 
    } 
    } 
 }, 1000, 5000, TimeUnit.MILLISECONDS); 

理由:

第1:Timer在執行所有定時任務的時候只會創建一個線程。如果某個任務執行時間過長,那麼將破壞其他TimeTask的定時精確性。

第2:如果TimerTask拋出一個UncheckedException,那麼Timer將表現出很挫的行為。Timer並不捕獲異常,因此當TimerTask拋出UncheckedException時候將終止定時線程,比如常見的一個NullPointerException。這種情況下,Timer不會恢復線程執行,而是會錯誤的任務整個Timer都取消掉。因此,已經被調度但尚未執行的Task將不會執行了,新的任務也不會調度,也就是常見的線程洩露。

而ScheduledThreadPoolExecutor能正確處理這些表現出錯誤行為的任務。

因此,如果您的JDK是5.0以上的,那麼建議不要使用過時的Timer類了。

最後,如果要用到高級功能,比如在某個星期的周五,在國慶節當天的幾點幾分,在每天凌晨幾點幾分執行之類的定時任務,就需要用到大名鼎鼎的Quartz框架了,一般用法:

SchedulerFactory sf = new StdSchedulerFactory(); 
 Scheduler sched = sf.getScheduler(); 
 JobDetail job = newJob(SimpleJob.class) 
    .withIdentity("job1", "group1") 
    .build(); 
 
 CronTrigger trigger = newTrigger() 
    .withIdentity("trigger1", "group1") 
    .withSchedule(cronSchedule("0/20 * * * * ?")) 
    .build(); 
 
 Date ft = sched.scheduleJob(job, trigger); 
 sched.start(); 

據我所知這個就是定時任務的最佳實踐了,不知道大家還有沒有更好的建議。

Copyright © Linux教程網 All Rights Reserved