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 :

Limiter le temps d'exécution d'une méthode


Sujet :

Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    103
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 103
    Points : 110
    Points
    110
    Par défaut Limiter le temps d'exécution d'une méthode
    Bonjour,

    Je réalise un test sur un algorithme pseudo-polynomial. Je souhaiterait limiter le temps d'exécution de la méthode contenant l'algorithme.

    Ma première idée a été d'utiliser des threads pour tuer le processus quand la limite est dépassée. C'était assez facile à faire en utilisant la méthode depreciée stop().
    J'aimerai bien que mon programme survive au prochains passages de versions et j'ai donc cherché une autre solution.
    La solution présentée dans la plupart des tutos consiste à créer un timer à la main et à tester le temps. L'avantage est que je n'ai plus besoin de threads mais je dois modifier le code de ma méthode. Je trouve ça encore plus nul.

    Est-ce que quelqu'un à une solution élégante à me proposer ?

    merci

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Ouep, tu peux utliser la classe Thread pour ça. Il te suffit de paramétrer ton thread avec la méthode Thread.join() avant de le lancer en spécifiant le nombre de millisec que tu veux donner à ton processus pour s'exécuter.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    103
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 103
    Points : 110
    Points
    110
    Par défaut
    La méthode join() mer permet d'interrompre facilement un thread au bout d'un certain temps. Mais comment tuer le thread sans utiliser la méthode stop() dans l'exemple suivant
    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
     
    public class ExThread extends Thread{
     
    	public ExThread(String name) {
    		super();
    		this.setName(name);
    	}
     
     
    	public void run() {
    		for(int i=0;i<5000;i++) {
    			System.out.println("Thread nommé : " + this.getName()+" - itération : " + i);
    		}
    	}
     
     
    	static public void main(String argv[]) {
    		ExThread thr1 = new ExThread("Toto");
    		try {
     
    			thr1.start();
    			thr1.join(1);
    			thr1.stop(); //deprecated : que faire pour arreter thr1 sans modifier thr1.run()  ?
    			System.out.println("\n\nthread principal\n\n");
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }

  4. #4
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par nono_31
    Bonjour,

    Je réalise un test sur un algorithme pseudo-polynomial. Je souhaiterait limiter le temps d'exécution de la méthode contenant l'algorithme.

    Ma première idée a été d'utiliser des threads pour tuer le processus quand la limite est dépassée. C'était assez facile à faire en utilisant la méthode depreciée stop().
    J'aimerai bien que mon programme survive au prochains passages de versions et j'ai donc cherché une autre solution.
    La solution présentée dans la plupart des tutos consiste à créer un timer à la main et à tester le temps. L'avantage est que je n'ai plus besoin de threads mais je dois modifier le code de ma méthode. Je trouve ça encore plus nul.

    Est-ce que quelqu'un à une solution élégante à me proposer ?

    merci
    Il faut que la méthode contenant ton algorithme "prévoit" des endroits où elle peut s'arrêter :
    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
    private boolean interrupt;
     
    public void method() throws InterruptedException {
        //début du calcul
        checkInterrupted();
        //suite du calcul
        checkInterrupted();
        //fin du calcul
    }
     
    public synchronized void checkInterrupted() throws InterruptedException {
        if(interrupt) {
            throw new InterruptedException();
        }
    }
     
    public synchronized void interrupt() {
        interrupt = true;
    }
    Ensuite il suffit d'appeler interrupt depuis un autre thread...
    Tu peux t'inspirer (par exemple) de ce post: http://www.developpez.net/forums/sho...d.php?t=395029

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    103
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 103
    Points : 110
    Points
    110
    Par défaut
    Merci pour ta réponse.

    Justement, je ne souhaite pas modifier la classe de mon algorithme. Je pourrais bien sur le modifier exclusivement pour les tests, mais je cherche une réponse générique me permettant d'interrompre ce thread. Je pourrai ainsi l'utiliser pour d'autres algos.

    L'algorithme n'utilise aucune structure de données partagée et donc il n'y a pas de risques (dans mon cas) à utiliser la méthode stop().
    Quels sont les autres risques dues à l'utilisation de cette méthode dépréciée ?

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Citation Envoyé par nono_31
    La méthode join() mer permet d'interrompre facilement un thread au bout d'un certain temps. Mais comment tuer le thread sans utiliser la méthode stop() dans l'exemple suivant
    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
     
    public class ExThread extends Thread{
     
    	public ExThread(String name) {
    		super();
    		this.setName(name);
    	}
     
     
    	public void run() {
    		for(int i=0;i<5000;i++) {
    			System.out.println("Thread nommé : " + this.getName()+" - itération : " + i);
    		}
    	}
     
     
    	static public void main(String argv[]) {
    		ExThread thr1 = new ExThread("Toto");
    		try {
     
    			thr1.start();
    			thr1.join(1);
    			thr1.stop(); //deprecated : que faire pour arreter thr1 sans modifier thr1.run()  ?
    			System.out.println("\n\nthread principal\n\n");
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }
    La méthode join() est précisément celle qu'il te faut. Simplement, il y a une erreur dans ton code. La méthode join() doit être appelée avant start(). Par ailleurs, il est inutile d'appeler stop() après join() puisque le processus s'arrêtera obligatoirement après le temps que tu as défini.
    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
    public class ExThread extends Thread{
    	public ExThread(String name) {
    		super();
    		this.setName(name);
    	}
    	public void run() {
    		for(int i=0;i<5000;i++) {
    			System.out.println("Thread nommé : " + this.getName()+" - itération : " + i);
    		}
    	}
    	static public void main(String argv[]) {
    		ExThread thr1 = new ExThread("Toto");
    		try {
    			thr1.join(1); //le thread s'arrêtera environ 1 millisec après avoir démarré
    			thr1.start();
    			System.out.println("\n\nthread principal\n\n");
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }

  7. #7
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par verbose
    La méthode join() est précisément celle qu'il te faut.
    Pas du tout, la méthode join() est bloquante dans le thread courant, avec éventuellement un timeout, mais en aucun cas cela stoppe le thread qui exécute le traitement long, celui sur lequel tu appelles join() !

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    103
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 103
    Points : 110
    Points
    110
    Par défaut
    Citation Envoyé par ®om
    Pas du tout, la méthode join() est bloquante dans le thread courant, avec éventuellement un timeout, mais en aucun cas cela stoppe le thread qui exécute le traitement long, celui sur lequel tu appelles join() !
    Je suis d'accord, la modification proposée ne marche pas (le processus long s'exécute en entier).

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Oui, exact, dsl. C'est vrai qu'en y réfléchissant join() définit un timeout et non une durée de vie.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    A défaut de solution "générique" pour arrêter un thread, je te propose une classe qui exécute en boucle un fragment de code en appelant une méthode de vérification à chaque itération :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public abstract class Stoppable extends Thread {
    	public final void run() {
    		while(doesContinue())
    			fragment();
    	}
    	protected abstract void fragment();
    	protected abstract boolean doesContinue();
    }

Discussions similaires

  1. Limiter le temps d'exécution d'une requête MySQL
    Par Ceubex dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 11/12/2014, 21h22
  2. limiter le temps d'exécution d'une commande
    Par luckyvae dans le forum Linux
    Réponses: 1
    Dernier message: 15/03/2010, 15h23
  3. Limiter le temps d'exécution d'une DLL
    Par RTN14 dans le forum Débuter
    Réponses: 7
    Dernier message: 12/10/2009, 15h58
  4. Réponses: 7
    Dernier message: 03/04/2008, 10h40
  5. Affichage du temps d'exécution d'une requête
    Par milka dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 22/03/2004, 17h48

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