Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I schedule a task to run once?

I want to delay doing something, along the lines of setting a countdown timer that will "do a thing" after a certain amount of time.

I want the rest of my program to keep running while I wait, so I tried making my own Thread that contained a one-minute delay:

public class Scratch {     private static boolean outOfTime = false;      public static void main(String[] args) {         Thread countdown = new Thread() {             @Override             public void run() {                 try {                     // wait a while                     System.out.println("Starting one-minute countdown now...");                     Thread.sleep(60 * 1000);                      // do the thing                     outOfTime = true;                     System.out.println("Out of time!");                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }         };         countdown.start();          while (!outOfTime) {             try {                 Thread.sleep(1000);                 System.out.println("do other stuff here");             } catch (InterruptedException e) {                 e.printStackTrace();             }         }     } } 


While this worked, more-or-less, it seemed like there should be a better way of doing this.

After some searching, I found a bunch of questions like these but they don't really address what I'm trying to do:

  • How do I schedule a task to run at periodic intervals?
  • How i can run my TimerTask everyday 2 PM
  • How to run certain task every day at a particular time using ScheduledExecutorService?
  • Java execute task with a number of retries and a timeout

I don't need anything this complicated; I just want to do a single thing after a certain amount of time while letting the rest of the program still run.

How should I go about scheduling a one-time task to "do a thing"?

like image 530
azurefrog Avatar asked Dec 16 '15 23:12

azurefrog


People also ask

How do I run a scheduled task only once?

There's no way to automatically disable a scheduled task on a given date so if you're looking to run a scheduled task only once, you're going to have to add an extra action to the task. The action is going to run a script that is going to disable the task.

How do I schedule a program to run automatically?

To schedule an automatic task on your Windows computer, you'll first have to open the Task Scheduler. Here's what you've to do: Go to the Start menu search bar, type in 'task scheduler,' and select the best match. In the Task Scheduler menu, right-click on the Task Scheduler Library, and select New Folder…

How do I schedule a program to run automatically in Windows 10?

Open Start, Search for "Task Scheduler" and press enter to open "Task Scheduler". Right-click on the "Task Scheduler Library" and click on the "New Folder" option. Enter the name of the New folder and click on the "OK" button. Navigate the following: Task Scheduler Library > New Folder, then click on "Create Task".


1 Answers

While the java.util.Timer used to be a good way to schedule future tasks, it is now preferable1 to instead use the classes in the java.util.concurrent package.

There is a ScheduledExecutorService that is designed specifically to run a command after a delay (or to execute them periodically, but that's not relevant to this question).

It has a schedule(Runnable, long, TimeUnit) method that

Creates and executes a one-shot action that becomes enabled after the given delay.


Using a ScheduledExecutorService you could re-write your program like this:

import java.util.concurrent.*;  public class Scratch {     private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);     public static void main(String[] args) {         System.out.println("Starting one-minute countdown now...");         ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() {             @Override             public void run() {                 // do the thing                 System.out.println("Out of time!");             }}, 1, TimeUnit.MINUTES);          while (!countdown.isDone()) {             try {                 Thread.sleep(1000);                 System.out.println("do other stuff here");             } catch (InterruptedException e) {                 e.printStackTrace();             }         }         scheduler.shutdown();     } } 

One of the nice things you get by doing things this way is the ScheduledFuture<?> object you get back from calling schedule().

This allows you to get rid of the extra boolean variable, and just check directly whether the job has run.

You can also cancel the scheduled task if you don't want to wait anymore by calling its cancel() method.


1See Java Timer vs ExecutorService? for reasons to avoid using a Timer in favor of an ExecutorService.

like image 93
azurefrog Avatar answered Sep 23 '22 00:09

azurefrog