2

我需要在一天中的特定时间运行一个可调用的。一种方法是计算现在和期望时间之间的时间差异,并使用 executor.scheduleAtFixedRate。

有更好的主意吗?

executor.scheduleAtFixedRate(command, TIMEDIFF(now,run_time), period, TimeUnit.SECONDS))

4

4 回答 4

11

对于这种事情,请继续安装Quartz。EJB 对这种事情有一些支持,但实际上您只希望 Quartz 用于计划任务。

话虽如此,如果您坚持自己做(我不建议这样做),请使用ScheduledThreadPoolExecutor.

ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(4);
ScheduledFuture<?> future =
  executor.scheduleAtFixedRate(runnable, 1, 24, TimeUnit.HOUR);

它将Runnable每天运行,初始延迟为一小时。

或者:

Timer timer = new Timer();
final Callable c = callable;
TimerTask task = new TimerTask() {
  public void run() {
    c.call();
  }
}
t.scheduleAtFixedRate(task, firstExecuteDate, 86400000); // every day

Timer有一个更简单的接口,并在 1.3 中引入(另一个是 1.5),但是一个线程执行所有任务,而第一个线程允许您对其进行配置。PlusScheduledExecutorService有更好的关闭(和其他)方法。

于 2009-01-13T08:26:10.250 回答
2

您可以使用JDK Timer并且不需要计算时间差:

Timer timer = new Timer();
Date executionDate = new Date();
long period = 24 * 60 * 60 * 1000;
timer.scheduleAtFixedRate(
    new TimerTask() {
        @Override
        public void run() {
            // the task
        }
    },
    executionDate,
    period);
于 2009-01-13T09:01:18.137 回答
2

Quartz 是一个好主意,但根据您的需要,可能有点矫枉过正。我认为你真正的问题是试图将你的服务塞进一个 servlet,而你实际上并没有监听传入的 HttpServletRequests。相反,请考虑使用 ServletContextListener 来启动您的服务和 Timer,正如 Maurice 建议的那样:

网页.xml:

<listener>
  <listener-class>com.myCompany.MyListener</listener-class>
</listener>

然后你的班级看起来像这样:

public class MyListener implements ServletContextListener {

    /** the interval to wait per service call - 1 minute */
    private static final int INTERVAL = 60 * 60 * 1000;

    /** the interval to wait before starting up the service - 10 seconds */
    private static final int STARTUP_WAIT = 10 * 1000;

    private MyService service = new MyService();
    private Timer myTimer;

    public void contextDestroyed(ServletContextEvent sce) {
        service.shutdown();
        if (myTimer != null)
                myTimer.cancel();
    }

    public void contextInitialized(ServletContextEvent sce) {
        myTimer = new Timer();
        myTimer.schedule(new TimerTask() {
                public void run() {
                        myService.provideSomething();
                }
        },STARTUP_WAIT, INTERVAL
      );
    }
}
于 2009-05-13T18:23:38.690 回答
1

我会推荐使用Quartz 框架。这将允许您以类似 cron 的方式安排作业。

于 2009-01-13T08:26:52.123 回答