2009-08-12 68 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();