How to schedule a Callable to run on a specific time?

断了今生、忘了曾经 提交于 2020-01-01 17:51:08

问题


I need to run a callable at a specific time of day. One way to do it is to calculate the timediff between now and the desired time , and to use the executor.scheduleAtFixedRate .

Have a better idea?

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


回答1:


For this kind of thing, just go ahead and install Quartz. EJB has some support for this kind of thing but really you just want Quartz for scheduled tasks.

That being said, if you insist on doing it yourself (and I'd recommend not), use the ScheduledThreadPoolExecutor.

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

which will run the Runnable every day with an initial delay of one hour.

Or:

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 has a somewhat simpler interface and was introduced in 1.3 (the other is 1.5) but a single thread executes all tasks whereas the first one allows you to configure that. Plus ScheduledExecutorService has nicer shutdown (and other) methods.




回答2:


I would recommend using Quartz Framework. This will allow you to schedule jobs in a cron like fashion.




回答3:


You can user JDK Timer and dont need to calculate the time difference:

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);



回答4:


Quartz is a great idea, but might be a bit of overkill depending on what you need. I think youre real issue is trying to cram your service into a servlet, when you aren't actually listening to incoming HttpServletRequests. Instead, consider using a ServletContextListener to start up your service, and a Timer, as Maurice suggested:

web.xml:

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

And then your class looks like this:

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


来源:https://stackoverflow.com/questions/438312/how-to-schedule-a-callable-to-run-on-a-specific-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!