8

I'm trying to get a function to be called every day. Right now my code is as follows:

do {
    Thread.sleep(1000*60*60*24);
    readInFile();
} while (true);

The issue is that it is being called every day plus the time it takes to execute the function readInFile. Is there a way to do a callback or something to go off every 24 hours?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Ted pottel
  • 6,869
  • 21
  • 75
  • 134
  • 18
    Schedule an application to execute periodically using the host task scheduling system. (Such as `cron` or Windows Task Scheduler for example.) Sleeping a thread for 24 hours is generally a bad idea. – David Oct 13 '15 at 14:46
  • 1
    You could calculate the time it next needs to run. Then sleep for something like a minute and compare the current time with the calculated time. – Jan Henke Oct 13 '15 at 14:46
  • If it has to be pure Java, I would look into Executors.newScheduledThreadPool. Create your pool with a size of one and give it a Runnable that runs your readInFile() method. – jgitter Oct 13 '15 at 14:47
  • You could also use another thread to execute the function, keeping this one active. – Dean Meehan Oct 13 '15 at 14:47
  • Or creep up on it by sleeping for 12 hours, 6, 3 and so on down to a second,say, recalculating the ms of sleep time remaining using the real-time clock. – Martin James Oct 13 '15 at 14:48
  • why dont u try quartz? – jpganz18 Oct 13 '15 at 18:08

3 Answers3

7

You can use ScheduledExecutorService.scheduleAtFixedRate method to invoke a Runnable at a fixed rate.

Sample code to invoke a runnable every day (with no initial delay):

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(myRunnable, 0, 1, TimeUnit.DAYS);
Tunaki
  • 132,869
  • 46
  • 340
  • 423
5

You can try this:

Timer timer = new Timer ();
TimerTask t = new TimerTask () {
    @Override
    public void run () {
        // some code
    }
};

timer.schedule (t, 0l, 1000*60*60*24);

or else you can use the ScheduledExecutorService

An ExecutorService that can schedule commands to run after a given delay, or to execute periodically.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • That is not going to be any better than sleep calls. – Martin James Oct 13 '15 at 14:49
  • `s/schedule/scheduleAtFixedRate/` – zapl Oct 13 '15 at 14:51
  • @MartinJames:- Hmm..ScheduledExecutorService will do the trick. Tunaki has hit it. – Rahul Tripathi Oct 13 '15 at 14:53
  • 1
    `Timer`/`TimerTask` can do the right thing too but you need to use one of the "AtFixedRate" versions: https://docs.oracle.com/javase/8/docs/api/java/util/Timer.html#scheduleAtFixedRate-java.util.TimerTask-long-long- what you do is "for repeated fixed-delay execution" which has the same problem as a fixed sleep. – zapl Oct 13 '15 at 14:55
2

You can use a scheduler such as Quartz or Spring to set the code to be run once per day.

Spring http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html

http://spring.io/guides/gs/scheduling-tasks/

//1:01 am every day
@Scheduled(cron = "0 1 1 * * ?")
public void readDaily() {
  readInFile();
}

Quartz https://quartz-scheduler.org

JobDetail job = new JobDetail();
    job.setName("dummyJobName");
    job.setJobClass(HelloJob.class);

    //configure the scheduler time
    Trigger trigger = new CronTrigger("trigger1", "group1");
    trigger.setCronExpression("0 0 15 * * ?"); //3pm every day

    //schedule it
    Scheduler scheduler = new StdSchedulerFactory().getScheduler();
    scheduler.start();
    scheduler.scheduleJob(job, trigger);
Ann Addicks
  • 915
  • 12
  • 25