【问题标题】:How to schedule a Callable to run on a specific time?如何安排 Callable 在特定时间运行?
【发布时间】:2009-01-13 08:23:37
【问题描述】:

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

有更好的主意吗?

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

【问题讨论】:

    标签: java scheduling callable


    【解决方案1】:

    对于这种事情,请继续安装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),但单个线程执行所有任务,而第一个线程允许您对其进行配置。另外ScheduledExecutorService 有更好的关闭(和其他)方法。

    【讨论】:

      【解决方案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);
      

      【讨论】:

      • 是的,这就是他在原帖中的意思。 :)
      • 这将在代码运行时立即执行第一次。当我阅读原始帖子时,他不希望第一次执行要等到所需的时间。
      • 我没试过代码,文档指定执行是“在指定时间开始”。
      【解决方案3】:

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

      web.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
            );
          }
      }
      

      【讨论】:

        【解决方案4】:

        我建议使用Quartz Framework。这将允许您以类似 cron 的方式安排作业。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-11-24
          • 2020-09-21
          • 2013-11-27
          • 1970-01-01
          • 2017-12-13
          • 1970-01-01
          • 2012-09-18
          • 2022-01-24
          相关资源
          最近更新 更多