198 votes

Comment planifier une tâche périodique en Java ?

J'ai besoin de planifier l'exécution d'une tâche à un intervalle de temps fixe. Comment puis-je le faire avec le support de longs intervalles (par exemple toutes les 8 heures) ?

J'utilise actuellement java.util.Timer.scheduleAtFixedRate . Est-ce que java.util.Timer.scheduleAtFixedRate supporte-t-il de longs intervalles de temps ?

285voto

b_erb Points 8869

Utilisez un ScheduledExecutorService :

 private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
 scheduler.scheduleAtFixedRate(yourRunnable, 8, 8, TimeUnit.HOURS);

1 votes

Si vous voulez que cette opération soit exécutée tous les jours à une heure précise, il n'y a pas de bonne façon de le faire, parce que la fonction TimeUnit s'applique à la fois à la initialDelay et le period . Le fonctionnement toutes les 24 heures sera perturbé par l'entrée en vigueur de l'heure d'été. TimeUnit de DAYS ne vous permet pas de spécifier un système de initialDelay . (Je pense que l'implémentation interne de ScheduledExecutorService convertit les données de la base de données en une base de données. DAYS à des nanosecondes de toute façon).

48voto

Jorge Points 6168

Vous devriez jeter un coup d'œil à Quartz il s'agit d'un cadre Java qui fonctionne avec les éditions EE et SE et qui permet de définir des tâches à exécuter à un moment précis.

24voto

Shessuky Points 231

Essayez de cette façon ->

Tout d'abord, créez une classe TimeTask qui exécute votre tâche, elle ressemble à ceci :

public class CustomTask extends TimerTask  {

   public CustomTask(){

     //Constructor

   }

   public void run() {
       try {

         // Your task process

       } catch (Exception ex) {
           System.out.println("error running thread " + ex.getMessage());
       }
    }
}

ensuite, dans la classe principale, vous instanciez la tâche et l'exécutez périodiquement à partir d'une date spécifiée :

 public void runTask() {

        Calendar calendar = Calendar.getInstance();
        calendar.set(
           Calendar.DAY_OF_WEEK,
           Calendar.MONDAY
        );
        calendar.set(Calendar.HOUR_OF_DAY, 15);
        calendar.set(Calendar.MINUTE, 40);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        Timer time = new Timer(); // Instantiate Timer Object

        // Start running the task on Monday at 15:40:00, period is set to 8 hours
        // if you want to run the task immediately, set the 2nd parameter to 0
        time.schedule(new CustomTask(), calendar.getTime(), TimeUnit.HOURS.toMillis(8));
}

6 votes

Pour rendre le code plus lisible, vous pouvez changer l'argument final de l'appel à la planification en TimeUnit.HOURS.toMillis(8).

0 votes

La documentation de Timer recommande d'utiliser le cadre Executor à la place.

14voto

Aride Chettali Points 11

Utiliser Google Guava AbstractScheduledService comme indiqué ci-dessous :

public class ScheduledExecutor extends AbstractScheduledService {

   @Override
   protected void runOneIteration() throws Exception {
      System.out.println("Executing....");
   }

   @Override
   protected Scheduler scheduler() {
        return Scheduler.newFixedRateSchedule(0, 3, TimeUnit.SECONDS);
   }

   @Override
   protected void startUp() {
       System.out.println("StartUp Activity....");
   }

   @Override
   protected void shutDown() {
       System.out.println("Shutdown Activity...");
   }

   public static void main(String[] args) throws InterruptedException {
       ScheduledExecutor se = new ScheduledExecutor();
       se.startAsync();
       Thread.sleep(15000);
       se.stopAsync();
   }
}

Si vous avez plus de services comme celui-ci, alors l'enregistrement de tous les services dans ServiceManager sera bon car tous les services peuvent être démarrés et arrêtés ensemble. Lire aquí pour en savoir plus sur ServiceManager.

10voto

Belizzle Points 167

Si vous voulez vous en tenir à java.util.Timer vous pouvez l'utiliser pour planifier à de grands intervalles de temps. Il vous suffit d'indiquer la période pour laquelle vous souhaitez effectuer des prises de vue. Consultez la documentation aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X