Je veux retarder quelque chose, comme le réglage d’un compte à rebours qui "fera quelque chose" après un certain temps.
Je veux que le reste de mon programme continue à fonctionner pendant que j'attends, alors j'ai essayé de créer ma propre Thread
qui contenait un délai d'une minute:
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();
}
}
}
}
.__ Bien que cela ait fonctionné plus ou moins, il semblait qu'il devrait y avoir une meilleure façon de le faire.
Après quelques recherches, j'ai trouvé un tas de questions comme celles-ci mais elles ne traitent pas vraiment de ce que j'essaie de faire:
Je n'ai besoin de rien d'aussi compliqué. Je veux juste faire une seule chose après un certain temps tout en laissant le reste du programme s'exécuter.
Comment devrais-je planifier une tâche ponctuelle pour "faire une chose"?
Alors que Java.util.Timer
était un bon moyen de planifier des tâches futures, il est maintenant préférable1 d'utiliser à la place les classes du package Java.util.concurrent
.
Il existe une ScheduledExecutorService
spécialement conçue pour exécuter une commande après un délai (ou pour les exécuter périodiquement, mais cela ne concerne pas cette question).
Il a une méthode schedule(Runnable, long, TimeUnit)
qui
Crée et exécute une action ponctuelle qui devient activée après le délai donné.
En utilisant une ScheduledExecutorService
, vous pouvez ré-écrire votre programme comme ceci:
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();
}
}
Une des choses intéressantes que vous obtenez en faisant les choses de cette façon est l’objet ScheduledFuture<?>
que vous obtenez en appelant schedule()
.
Cela vous permet de vous débarrasser de la variable supplémentaire boolean
et de vérifier directement si le travail a été exécuté.
Vous pouvez également annuler la tâche planifiée si vous ne souhaitez plus attendre en appelant sa méthode cancel()
.
1Voir Java Timer vs ExecutorService? pour éviter d'utiliser une Timer
en faveur d'une ExecutorService
.
Merci cela a fonctionné pour moi. J'ai utilisé le planificateur pour planifier une tâche à un batchinterval calculé au moment de l'exécution.
manualTriggerBatchJob.setSchedulingProperties(pblId, batchInterval);
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(5);
@SuppressWarnings("unchecked")
ScheduledFuture scheduledFuture =
scheduledExecutorService.schedule(manualTriggerBatchJob,
batchIntervalInMin,TimeUnit.MILLISECONDS);