2010-03-29 49 views

回答

7

您正在尋找的是一個調度程序。 Quartz可能是Java世界中最常用的調度程序,但如果您已經在使用該框架,Spring會提供一些有趣的調度功能。

無論您選擇哪個調度程序,您通常都會指定要發生的操作(有時稱爲「作業」)和發生的時間(Quartz術語中的「觸發器」)。在你的情況下,你會設置觸發器每天在午夜運行,當它觸發時,它會根據你的工作規定來做你需要做的任何事情。

1

作爲一個庫,您可以使用Quartz並設置觸發器在每晚午夜運行。我認爲簡單的觸發器應該可以完成這項工作。

或者,您可以通過使用單獨的線程並休眠直到下一個午夜來實現Quartz自己做些什麼。

-1

如果你不想要Quartz或任何其他類似的框架,你可以簡單地使用ScheduledExecutorServicescheduleAtFixedRate方法來代替(這裏有一個如何在JavaDoc中實例化的例子)。

你唯一需要考慮的是如何計算第一天的開始。

編輯

由於Jarnbjo提到:這將無法生存夏令時間開關,跨越式秒。所以在使用Executor時要注意這一點。

+0

這將無法正常工作,因爲午夜不會以固定的速度重新分配。 – jarnbjo 2010-03-29 11:18:09

+0

當然,但在大多數情況下,這並不重要。 – Hardcoded 2010-03-29 11:19:32

+0

如果您想在午夜執行某些操作,那麼在11PM或1AM時執行該作業可能不太合適。其中「大多數情況下」是這種可接受的行爲? – jarnbjo 2010-03-29 11:39:16

0

這個問題的答案曾經是Quartz。這是Java中調度的事實標準。它很容易使用,但它有點重量級。如果你不關心作業的集羣調度或JDBC存儲,石英可能會過度殺傷。

謝天謝地,Spring 3.0帶有新的調度功能。這些允許簡單的「做這個evey 30秒」或者「每天在午夜做這個」類型的調度,而不使用石英。如果您已經在使用彈簧,設置起來非常簡單。

例子:

<task:scheduler id="scheduler" pool-size="10"/> 

<task:scheduled-tasks scheduler="scheduler"> 
    <task:scheduled ref="anotherObject" method="anotherMethod" cron="* * 00 * * *"/> 
</task:scheduled-tasks> 

這將導致法 'anotherMethod' 被稱爲你的bean命名爲 'anotherObject' 每天午夜的。更多的信息可以在春季網站上找到:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html

+1

嗯,調用石英重量級與Spring相比...... – laura 2010-03-29 11:47:26

+0

@laura很多人已經將Spring作爲IoC的依賴項。我不建議只將Spring包含在這個功能中,但如果你使用的是彈簧,那麼這比重新使用所有的石英輕。 – 2010-03-29 20:12:21

0

你不需要一個龐大的框架。像這樣的東西應該工作。

import java.util.*; 
public class Midnight { 
    public static void main(String args[]) { 
     MidnightCowboy mc = new MidnightCowboy(); 
     mc.start(); 
     // on with you normal program flow (if any) here 
    } 
} 

class MidnightCowboy extends Thread { 
    static final boolean COWS_COME_HOME = false; 
    // Whatever data you need should go here 

    public void run() { 
     while (! COWS_COME_HOME) { 
      GregorianCalendar now = new GregorianCalendar(); 
      long nowMilli = now.getTimeInMillis(); 
      now.add(Calendar.DAY_OF_MONTH, 1);  // probably an easier way to set the time to the next midnight 
      now.set(Calendar.HOUR_OF_DAY, 0); 
      now.set(Calendar.MINUTE, 0); 
      now.set(Calendar.SECOND, 0); 
      now.set(Calendar.MILLISECOND, 0); 
      long midnightMilli = now.getTimeInMillis(); 
      long delta = midnightMilli - nowMilli; 
      System.out.println("Waiting " + delta + " milliseconds until midnight."); 
      // How many milliseconds until the next midnight? 
      try { 
       sleep(delta); 
       doSomething(); 
      } catch (InterruptedException e) { 
       System.err.println("I was rudely interrupted!"); 
      } 
     } 
    } 

    void doSomething() { 
     // whatever 
    } 
} 
0

如果你想比整個圖書館更輕量級的解決方案,我發現了一個非常簡單的實現here。它基本上是一個Timer類。

當經由Start()方法首先執行類,代碼獲取的當前時間的日期時間,然後得到午夜的日期時間對象,並以得到的時間,直到它是午夜減去2倍。

此時,它設置定時器間隔並啓動定時器。現在,當達到間隔並且定時器觸發其事件時,我使用相同的過程重置定時器。這將使間隔爲24.當此計時器到期時,它將被重置並無限重複。