0

I am trying to schedule a task but the error window for missing the requested time is 1-2 seconds. Because of drift I wanted to check the time recursively and adjust it. I've run this code in short periods of time (max delay: 15 mins) and it worked very well. But the job will be scheduled for 8 to 12 hours from now in most of the cases.

    public void scheduleTask(LocalDateTime localDateTime)  {

        long delay = ChronoUnit.MILLIS.between(LocalDateTime.now(),localDateTime);
        if (delay < 30000) {
            ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            scheduler.schedule(() -> myTask() ,delay, TimeUnit.MILLISECONDS);
        }
        else {
            try {
                Thread.sleep(delay/2);
            } catch (InterruptedException ignored) {
            }

            scheduleTask(localDateTime);
        }
    }

I looked at various topics here but could not see a real solution. Mostly it is said that it is impossible to run a code in exact time because the schedulers operates based on delay and not on the given time.

Does calling the function recursively affect the computer in any aspect considering 8-12 hours period ? If yes, how should I overcome that ?

Saydemr
  • 5
  • 1
  • 5
  • What exactly are you trying to achieve? Why not directly schedule the task? You will most likely not encounter a problem when you schedule a task 12h into the future – Lino Sep 21 '20 at 10:27
  • Welcome to stack overflow. Please read the question guidelines here https://stackoverflow.com/help/how-to-ask and be advised that asking multiple questions in one is an option to have questions flagged for removal. – possum Sep 21 '20 at 10:34
  • @Lino the computer will be heavily used (most probably) for other purposes and I don't know how it affects the timer of scheduled task. I don't know how sensetive it is. – Saydemr Sep 21 '20 at 10:53

1 Answers1

-1

Try writting an int value into a file, with the int of the UNIX epoch you want your program to start an event. Call frequently a function that checks that value against the current int of UNIX epoch. If you need precision do it in async task. If you don't need precise time and don't need it to trigger outside the app, do it in some other event like create and resume.

If you need precision then: The main problem is to keep the app active. Sticky asynctasks could do that. Even when using sticky async task, you can make it idle (consume very little resources) by using Thread.sleep(30000); and thus checking the file less often.

If internet is present you could also think of firebase or some custom messaging system where server would pass the message with a cron job. Cron jobs on stable servers are a very reliable way of triggering something way in the future.

Marko Ilić
  • 43
  • 1
  • 1
  • 5