2009-08-12 48 views
3

我有一個應用程序需要按計劃完成一件事,並且只需要一件事,它將能夠輕鬆計算下一次需要運行的時間。它可能不需要從現在開始運行這個任務幾天或幾個月,但可能每隔幾毫秒就會在其他方面活躍起來。我需要在Java中長時間(幾天)睡覺

我正在尋找一個簡單的輕量級方法來調度一個任務運行。

+6

做了一些規格文件後,我也會遇到同樣的情況:D – 2009-08-12 13:18:50

+3

您是否試過Lunesta? – JonnyD 2009-08-12 13:18:54

+1

Java的不那麼無聊! :p – Jimmeh 2009-08-12 13:19:42

回答

4

如果您的Java應用程序的目的是要連續運行,那麼你可以使用Timer類調​​度執行

如果您的應用程序是不會再要連續運行其他的答案是正確的。 cron /任務調度程序是要走的路。

+2

更好的鏈接:http://java.sun.com/j2se/1.5.0/docs/api/java/util/Timer.html – 2009-08-12 14:06:23

+0

@Kevin謝謝你。每次發佈鏈接時,我都會忘記Java API網站上的框架問題。在將來必須更小心。 – Glen 2009-08-12 14:13:02

11

在Unix上,查看系統工具cronat

在Windows上,系統設置中有一個作業調度程序。

對於簡單的純Java解決方案,請嘗試Timer API

有關更復雜的純Java解決方案,請參閱quartz

+0

那麼這是顯而易見的。 – 2009-08-12 13:28:15

+2

你的觀點是? – 2009-08-12 13:31:52

+0

當然,提及這些可能對於有類似問題的新手Google員工很有用,但我只需要按計劃做一件事情,所有這些看起來都很重量級。我不認爲答案認爲發佈的問題的方面。 – 2009-08-12 13:37:13

0

只要使用java.util.concurrent,它就有一個預定的執行部件。您需要添加警戒條件以防止過度運行,或者在當前末尾添加下一個執行。

+0

如果我是你,我會遵循Aaron Digulla的建議。它看起來像java.util.concurrent中的類和功能是爲了線程調度而做的,而不是遠在將來的任務調度,它可能是非常不理想的。從這個意義上說,調度意味着要確定幾個任務如何輪流在一個CPU /內核上運行(以毫秒爲單位),而不是從現在開始幾天安排任務。 – Ricket 2009-08-12 13:36:11

1

那麼,如果你需要你的應用程序在特定時間運行,你可以安排一個cron作業。或者,您可以編寫一個簡單的課程,在特定時間安排課程。由於我不知道任何圖書館(從來沒有真的需要尋找一個圖書館),我很早以前就寫了一堂課來爲我自己安排一項任務。希望它可以幫助和在球場:

import java.util.*; 

public abstract class TimeMonitor extends Thread 
    { 
     protected double execution_time; 
     protected boolean execute_at_startup; 

     public TimeMonitor() 
      { 
       execute_at_startup = false; 
      } 

     public TimeMonitor(double time) 
      { 
       execution_time = time; 
       execute_at_startup = false; 
      } 

     public void startTimer() 
      { 
       setPriority(Thread.MIN_PRIORITY); 
       start(); 
      } 

     public void setTime(double time) 
      { 
       execution_time = time; 
      } 

     public void executeAtStartup() 
      { 
       execute_at_startup = true; 
      } 

     public void run() 
      { 
       if (execute_at_startup) 
        doTimedAction(); 

       while (true) 
        { 
         long runtime = (long)(execution_time * 3600 * 1000); 
         long now  = getTime(); 
         long sleep = 0; 

         // Calculate how long to way until first run 
         if (runtime > now) 
          sleep = runtime - now; 
         else 
          sleep = 24 * 3600 * 1000 - now + runtime; 

         try 
          { 
           Thread.sleep(sleep); 
          } 
         catch (InterruptedException e) 
          { 
           logError("Wait thread has been interrupted.", e); 
           continue; 
          } 

         doTimedAction(); 
        } 
      } 

     /** 
     * Calculates number of milliseconds from start of the day. 
     * 
     * @return Number of milliseconds. 
     */ 
     private long getTime() 
      { 
       Calendar cal = Calendar.getInstance(); 
       int hours = cal.get(Calendar.HOUR_OF_DAY); 
       int minutes = cal.get(Calendar.MINUTE); 
       int seconds = cal.get(Calendar.SECOND); 
       int millis = cal.get(Calendar.MILLISECOND); 

       return (hours * 3600 + minutes * 60 + seconds) * 1000 + millis; 
      } 

     private void doTimedAction() 
      { 
       try 
        { 
         performAction(); 
        } 
       catch (Throwable e) 
        { 
         logError("An error occured during timed execution.", e); 
        } 
      } 

     /** 
     * This method will be called when an error or a warning occures. 
     * 
     * @param msg 
     * @param e 
     */ 
     protected void logError(String msg, Throwable e) 
      { 
       System.out.println(msg); 
       e.printStackTrace(); 
      } 

     /** 
     * Action to be performed when scheduled time happens. 
     */ 
     protected abstract void performAction(); 
    } 

擴展使用它,像這樣:

 TimeMonitor archiver = new TimeMonitor() 
      { 
       protected void performAction() 
        { 
         // Do the task 
        } 
      }; 

     archiver.setTime(16.5); // Run at 4:30pm 
     archiver.startTimer();