IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Exécution de N tâches à intervalles pseudo réguliers


Sujet :

Java

  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 32
    Points : 47
    Points
    47
    Par défaut Exécution de N tâches à intervalles pseudo réguliers
    Bonjour

    J'ai besoin de pouvoir exécuter un certain nombre de tâches en parallèle et chacune de ces tâches doit exécuter une action simple et rapide à intervalle presque régulier (par exemple entre 5s et 6s de délai).

    Avec le code ci-dessous j'arrive à lancer plusieurs tâches en parallèle, mais chacune de ces tâches est exécutée à intervalle strictement régulier,
    il n'y a pas de partie variable dans le délai.

    Voyez-vous comment faire pour ajouter cette partie variable dans le délai d'exécution de chaque tâche ?

    Merci


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Activator extends TimerTask {
     
        	@Override
        	public void run() {
        		// do something
        	}
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public static void main(String[] args) throws Exception {
        Timer timer = new Timer(true);
        timer.scheduleAtFixedRate(new Activator(), 0, 2000); // ici le délai devrait être compris entre 2000 et 2300 ms par exemple
        timer.scheduleAtFixedRate(new Activator(), 0, 5000);
        timer.scheduleAtFixedRate(new Activator(), 0, 7000);
        // ...    	
        	}
        }

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Février 2013
    Messages
    191
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Février 2013
    Messages : 191
    Points : 472
    Points
    472
    Par défaut
    scheduleAtFixedRate() ça va être compliqué de lancer des tâches à des intervalles fixes variables en effet
    Ce que j'essaierai de faire, c'est de lancer la tâche suivante à la fin de l’exécution de la précédente tâche, comme ça tu peux fixer un délais différent.
    Ce n'est peut-être pas la meilleure solution, en tout cas je ne pense pas que tu arrivera à tes fins en utilisant uniquement la méthode scheduleAtFixedRate()

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2012
    Messages
    3 020
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2012
    Messages : 3 020
    Points : 16 092
    Points
    16 092
    Par défaut
    Utiliser la classe Random?

    Regarde du coté de la méthode nextInt.

  4. #4
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 32
    Points : 47
    Points
    47
    Par défaut
    Merci pour vos réponses.

    Comme pour Carhiboux ça n'est pas clair, je reprécise :
    Ce qui doit être variable c'est le délai entre chaque exécution d'une même tâche. Dans mon exemple je lance trois tâches, avec des délais fixes à 2000, 5000 et 7000 ms, mais ce que je voudrais c'est qu'à chaque exécution de chaque tâche le délai soit légérement différent. Par exemple pour la première tâche 2100, puis 2200, puis 2180, etc. Pour la deuxième 5075, puis 5123, etc.

    Donc effectivement je ne pense pas y arriver juste avec scheduleAtFixedRate(). Mais comme je ne maitrise pas ces aspects je ne sais pas trop quelles autres classes utiliser.
    Je vais voir si j'arrive à faire quelque chose avec l'idée de EyZox. Ca doit être faisable en annulant l'ordonnancement et en jouant sur le deuxième paramètre de la méthode plutôt que sur le dernier.
    Je continue à chercher.

    EDIT:
    si ça peut intéresser quelqu'un, je pense qu'une solution se trouve ici : http://www.tutorialspoint.com/java/j...ad_control.htm.
    Après quelques simplifications et quelques tests, j'arrive à faire ce que je veux. Je posterai un exemple de code un peu plus tard.

  5. #5
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    La solution la plus simple consiste effectivement à reprogrammer la tâche. Pour te simplifier le travail tu peux très bien créer un "ExecutorService" et un "wrapper" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    class DelayedExecutorService<T extends Runnable & Delayed> implements AutoCloseable {
        ScheduledExecutorService executor;
        /* ... Constructeurs & co. */
     
        public void scheduleAtRate(final T task) {
            class ReschedulingTask implements Runnable {
                public void run() {
                    task.run();
                    executor.schedule(ReschedulingTask.this, task.getDelay(MILLISECONDS), MILLISECONDS);
                }
            }
            executor.schedule(new ReschedulingTask(), task.getDelay(MILLISECONDS), MILLISECONDS);
        }
    }
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2012
    Messages
    3 020
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2012
    Messages : 3 020
    Points : 16 092
    Points
    16 092
    Par défaut
    Citation Envoyé par Eldergrim Voir le message
    Comme pour Carhiboux ça n'est pas clair, je reprécise :
    Ce qui doit être variable c'est le délai entre chaque exécution d'une même tâche. Dans mon exemple je lance trois tâches, avec des délais fixes à 2000, 5000 et 7000 ms, mais ce que je voudrais c'est qu'à chaque exécution de chaque tâche le délai soit légérement différent. Par exemple pour la première tâche 2100, puis 2200, puis 2180, etc. Pour la deuxième 5075, puis 5123, etc..
    Ben Carhiboux il avait très bien compris. Et il persiste à te dire que la classe Random avec sa méthode nextInt devrait te convenir.

    Tu me dis que tu veux pour la première tache, des valeurs aléatoires entre 2000 et 2300.

    Donc si tu fais un truc du genre :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Random randomGen= new Random();
    timer.scheduleAtFixedRate(new Activator(), 0, 2000 + randomGen.nextInt(300));

    Tu vas avoir un délais entre 2000 et 2300 (exclu).

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Février 2013
    Messages
    191
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Février 2013
    Messages : 191
    Points : 472
    Points
    472
    Par défaut
    Citation Envoyé par Carhiboux Voir le message
    Ben Carhiboux il avait très bien compris. Et il persiste à te dire que la classe Random avec sa méthode nextInt devrait te convenir.

    Tu me dis que tu veux pour la première tache, des valeurs aléatoires entre 2000 et 2300.

    Donc si tu fais un truc du genre :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Random randomGen= new Random();
    timer.scheduleAtFixedRate(new Activator(), 0, 2000 + randomGen.nextInt(300));

    Tu vas avoir un délais entre 2000 et 2300 (exclu).
    Il souhaite avoir un délais qui change entre chaque exécution de tâche, pas un délais de départ aléatoire qui va rester identique tout au long de l'exécution du timer.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2012
    Messages
    3 020
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2012
    Messages : 3 020
    Points : 16 092
    Points
    16 092
    Par défaut
    Je ne veux pas être désagréable, mais as tu essayé la solution que j'ai proposé avant de la critiquer et de la déclarer invalide?

    Je ne pense pas, car elle est parfaitement fonctionnelle.

    Si tu veux t'en assurer, tu peux essayer :

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	public static void main(String[] args) {
    		for(int i = 0 ; i < 10; i++){
    			Random rand = new Random();
    			System.out.println("Val = " + rand.nextInt(300));
    		}
    	}

    Donne en sortie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Val = 51
    Val = 214
    Val = 276
    Val = 243
    Val = 111
    Val = 188
    Val = 221
    Val = 159
    Val = 269
    Val = 233
    et à l’exécution suivante histoire de voir si les mêmes nombres reviennent toujours?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Val = 107
    Val = 119
    Val = 288
    Val = 151
    Val = 263
    Val = 282
    Val = 213
    Val = 153
    Val = 132
    Val = 6
    Donc je persiste et signe, Random et nextInt font parfaitement le boulot dans le cas proposé.

    Quand bien même tu instancierait une nouvelle instance de Random à chaque appel au main, tu auras une valeur différente avec nextInt(n) comprise dans l'intervalle [0;n[. Cf l'exemple au dessus.

  9. #9
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 32
    Points : 47
    Points
    47
    Par défaut
    Je persiste et signe, Carhiboux semble ne pas avoir compris
    Mais je ne vous jette pas la pierre Pierre, la nuance est subtile.

    Pour montrer ce que je voulais faire voici un exemple de code qui fonctionne :
    (Tu noteras l'usage de la méthode nextInt(), et pas seulement pour te faire plaisir, car elle m'est tout à fait utile)

    Est-ce plus clair maintenant ?

    J'espère que cet épisode ne te dissuaderas pas de répondre à une de mes éventuelles futures question.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    import java.util.Random;
     
    class RunnableDemo implements Runnable {
    	public int delay;
    	public Thread t;
    	private String threadName;
     
    	RunnableDemo(String name, int delay) {
    		this.threadName = name;
    		this.delay = delay;
    		System.out.println("Creating " + threadName);
    	}
     
    	public void run() {
    		System.out.println("Running " + threadName);
    		int delayLocal;
    		try {
    			for (int i = 10; i > 0; i--) {
    				delayLocal = this.delay + new Random().nextInt(500);
    				System.out.println("Thread: " + threadName + ", " + i + ", delay: " + delayLocal);
    				Thread.sleep(delayLocal);
    			}
    		} catch (InterruptedException e) {
    			System.out.println("Thread " + threadName + " interrupted.");
    		}
    		System.out.println("Thread " + threadName + " exiting.");
    	}
     
    	public void start() {
    		System.out.println("Starting " + threadName);
    		if (t == null) {
    			t = new Thread(this, threadName);
    			t.start();
    		}
    	}
    }
     
    public class TestThread {
    	public static void main(String args[]) {
    		RunnableDemo R1 = new RunnableDemo("Thread-1", 1000);
    		R1.start();
    		RunnableDemo R2 = new RunnableDemo("Thread-2", 3000);
    		R2.start();
    	}
    }

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2012
    Messages
    3 020
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2012
    Messages : 3 020
    Points : 16 092
    Points
    16 092
    Par défaut
    Si je n'ai pas compris, pourquoi à tu exactement utilisé la solution que j'ai proposé? Oo

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    delayLocal = this.delay + new Random().nextInt(500);
    Après, tu es passé par des Threads au lieu des Timer de ton message initial, mais ce n'était pas ta question initiale qui était de savoir comment introduire un peu d'aléatoire dans ton code.

    Mais bon, on va pas couper les cheveux en quatre, tu as ta solution, c'est le principal!

  11. #11
    Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 32
    Points : 47
    Points
    47
    Par défaut
    Le point sur lequel je butais n'était pas de générer de l'aléatoire, c'était de faire varier à chaque passage dans la boucle le délai entre chaque execution d'une tâche.
    Si tu as exécuté le bout de code que j'ai posté tu devrais voir ce que je veux dire.

    Mais comme tu l'écris, on ne va pas couper les cheveux en quatre. D'ailleurs c'est pas facile.

    Sur ce, je marque en résolu car effectivement le principal c'est que j'ai trouvé ma réponse.

    Merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WD16] Exécution d'un automate à intervalles réguliers
    Par DavidleVrai dans le forum WinDev
    Réponses: 4
    Dernier message: 17/07/2012, 17h26
  2. Empêcher la double exécution d'une tâche en arrière plan.
    Par Paul Van Walleghem dans le forum VB.NET
    Réponses: 2
    Dernier message: 29/08/2010, 16h12
  3. [WD-2007] Exécution automatique de tâches multiples sur Word
    Par Tinotlino dans le forum Word
    Réponses: 4
    Dernier message: 15/10/2009, 01h51
  4. Exécution d'une tâche au démarrage
    Par 84mickael dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 30/03/2008, 00h50
  5. [BES] Exécution périodique de tâches
    Par Bobby McGee dans le forum Autres
    Réponses: 5
    Dernier message: 04/02/2004, 17h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo