Planification en Java

  1. Planifier un processus à l’aide des méthodes d’interface ScheduledExecutorService en Java
  2. Planifier un thread à l’aide de la classe Timer en Java

La planification est le processus d’exécution d’une tâche ou d’une fonction à un intervalle de temps fixe. La planification trouve son utilisation dans l’exécution de processus par lots, l’envoi de déclencheurs basés sur des événements tels que les souhaits d’anniversaire, l’envoi de notifications push. Ces processus doivent s’exécuter à une heure bien définie en fonction des conditions et de l’intervalle de temps donnés.

Planifier un processus à l’aide des méthodes d’interface ScheduledExecutorService en Java

package scheduling;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class ScheduleTask {
    private static int counter = 0;

    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
        Runnable executeTask = () -> {
            counter++;
            System.out.println("Task" + counter);
        };

        ScheduledFuture<?> scheduleAtFixedRate = service.scheduleAtFixedRate(executeTask, 5, 1, TimeUnit.SECONDS);

        while (true) {
            Thread.sleep(1000);
            if (counter == 5) {
                System.out.println("Stopping the scheduled task!");
                scheduleAtFixedRate.cancel(true);
                service.shutdown();
                break;
            }
        }
    }
}

Dans le code ci-dessus, tout d’abord, une variable de compteur statique est initialisée à la valeur zéro. Le newScheduledThreadPool est une méthode statique de la classe Executors. La méthode crée un pool de threads qui doit s’exécuter périodiquement avec le paramètre indiqué dans la liste d’arguments. Ainsi, dans notre cas, un seul thread est créé pour l’exécution car le paramètre dans la liste d’arguments des méthodes définit le nombre de pools de threads. La méthode renvoie une instance de ScheduledExecutorService qui est stockée dans la variable de référence service et lève IllegalArgumentException si la taille du pool est inférieure à zéro.

Le Runnable est une interface que n’importe quelle classe peut étendre et est l’interface fonctionnelle. Il n’a qu’une seule méthode statique en tant que méthode run et est destiné à l’exécution du thread. En utilisant l’expression lambda exprimée sous la forme du symbole ()-> entre parenthèses et d’une flèche, la structure indique que nous ne transmettons aucun argument à la méthode run. Nous avons défini les instructions dans la définition de la méthode run. L’instruction présente à l’intérieur du bloc incrémentera la variable de compteur et imprimera la tâche dans la sortie de la console. Toutes ces instructions sont référencées par la variable appelée variable executeTask.

La variable de référence service appelle la méthode scheduleAtFixedRate de l’interface ScheduledExecutorService. La méthode crée et exécute la tâche périodique qui doit s’exécuter après le délai initial et plus tard dans la période donnée. Il faut quatre paramètres, une commande runnable qui est censée s’exécuter, et la variable initialDelay est le temps de retarder la première exécution, period désigne la durée entre les exécutions successives, et unit est l’unité de temps en secondes , minutes et heures. Le thread commence à s’exécuter dès que la méthode est appelée.

Dans la boucle while, d’abord, le thread en cours d’exécution est forcé de dormir. La méthode Thread.sleep() arrête temporairement le thread en cours d’exécution pour la durée définie. Le paramètre est le nombre en millisecondes pendant lequel le thread de travail actuel doit s’arrêter. La méthode lève IllegalArgumentException si la valeur est négative et InterruptedException si le thread en cours est interrompu. Plus tard, la valeur d’un compteur est vérifiée avec une valeur définie. Cette vérification est appliquée pour exécuter la méthode while un nombre défini de fois. Sinon, le bloc fonctionnera pour un nombre infini qui ne se terminera jamais. Dans le bloc while, la variable scheduleAtFixedRate appelle la méthode cancel, qui annule l’exécution en cours du thread. La fonction prend également un paramètre booléen indiquant si le thread en cours d’exécution peut interrompre ou non.

La méthode service.shutdown lance le processus d’arrêt dans lequel les tâches précédemment soumises sont censées être exécutées, et rien de nouveau n’est accepté.

La sortie du bloc de code ci-dessus est comme ci-dessous.

Task1
Task2
Task3
Task4
Task5
Stopping the scheduled task!

Planifier un thread à l’aide de la classe Timer en Java

Vous trouverez ci-dessous le bloc de code simple qui instancie deux objets de classe définis par l’utilisateur à l’aide de ses constructeurs. TimerImplementation est la classe définie par l’utilisateur pour le même. Une instance de Timer est créée et créera un nouveau thread. L’objet nouvellement créé d’un timer appellera alors la méthode scheduleAtFixedRate. Cette méthode prend les paramètres comme task qui doit être planifiée, delay retarde la tâche en millisecondes, et period est le temps en millisecondes pour l’exécution successive.

package timer;

import java.util.Timer;

public class UsingTimerClass {
    public static void main(String[] args) {
        TimerImplementation timer1 = new TimerImplementation("Thread1");
        TimerImplementation timer2 = new TimerImplementation("Thread2");

        Timer t = new Timer();
        t.scheduleAtFixedRate(timer1, 0, 2000);
        t.scheduleAtFixedRate(timer2, 0, 1000);
    }
}

Vous trouverez ci-dessous l’implémentation de la classe définie par l’utilisateur. La classe TimerImplementation étend la classe abstraite TimerTask qui contient une seule méthode abstraite nommée run. Nous étendons la classe TimerTask dans une classe définie par l’utilisateur, puis la méthode run est remplacée.

La classe a un constructeur défini par l’utilisateur qui définit le nom défini par l’utilisateur sur l’objet thread.

Nous pouvons donner une logique réelle dans la méthode run du thread. Il inclut une instruction comme print qui imprimera le nom du thread en cours d’exécution. Thread.currentThread().getName() renvoie le nom du thread en cours d’exécution. La méthode sleep est appelée via Thread1 qui interrompt l’exécution pendant 1000 millisecondes. La méthode sleep lève InterruptedException si un thread interrompt le thread actuel, et c’est pourquoi il est inclus dans le bloc try-catch.

package timer;

import java.util.TimerTask;

public class TimerImplementation extends TimerTask {

    private String name;

    public TimerImplementation(String n) {
        this.name = n;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " " + name);
        if ("Thread1".equalsIgnoreCase(name)) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Vous trouverez ci-dessous la sortie sans fin du code ci-dessus. Puisque nous n’avons défini aucune condition de fin dans la méthode run, le thread s’exécutera sans fin jusqu’à ce qu’un arrêt externe soit appliqué pour arrêter l’exécution du thread principal.

Timer-0 Thread1
Timer-0 Thread2
Timer-0 Thread2
Timer-0 Thread2
Timer-0 Thread1
Timer-0 Thread2
Timer-0 Thread2
Timer-0 Thread1
Timer-0 Thread2