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

avec Java Discussion :

Créer une méthode avec un timeout


Sujet :

avec Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    382
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 382
    Par défaut Créer une méthode avec un timeout
    Bonjour,

    j'aimerais savoir comment faire pour générer une méthode qui emet une exception timeout si le temps d'éxécution est trop long ? en effet, je dispose actuellement d'une méthode dont le temps d'éxécution met de 20 à 60 secondes. J'aimerais déclencher une exception au bout d'un temps x et bien sur arrêter le traitement de la méthode mais comment faire ?

    merci

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    c'est à toi, dans ta méthode, de mesurer ton temps de calcul et d'arrêter si tu dépasse un délai en lancant, par exemple, une exception. On ne peux pas le faire de l'extérieur de la méthode.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    382
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 382
    Par défaut
    donc je ne peux rien faire ici ?....

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    si tu veux le faire de l'extérieur, pas possible. En meme temps, tu prend la boucle de ton code qui prend le plus de temps et tu fait des check de temps dedans.

  5. #5
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Par défaut
    Il y a peut-etre moyen de le faire à l'exterieur avec un multi-thread
    A voir

  6. #6
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 679
    Par défaut
    Oui mais justement s'il confie a un autre thread la tache de mesurer le délai, alors, il ne pourra pas interrompre directement le thread qui s'occupe du traitement.

  7. #7
    Membre averti
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    40
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 40
    Par défaut
    Bonjour,
    comme l'a dit zouuc, je pense qu'il devrait y avoir moyen au moyen d'un thread qui serait lancer juste avant ton instruction bloquante.

    Ce thread ne ferais que lancer une exception qui serait a catché dans ta méthode au bout de X temps. Si tu a fini ton traitement avant la fin du temps, il suffit de faire appel à une méthode de ton thread qui ferme celui ci ou qui coupe du moins ton timer.

    Le fait que tu catch cette exception coupera l'effet bloquant.

    A plus tard

    ____________________________________________

    seulement 10 personnes peuvent comprendre ceci...

  8. #8
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par moufasa Voir le message
    Ce thread ne ferais que lancer une exception qui serait a catché dans ta méthode au bout de X temps.
    Ca marchera pas, tu va avoir le thread X qui exécute le code bloquant et le thread Y qui déclenche une exception au bout de n minutes. L'exception lancée par Y ne sera jamais vues par X puisque ce sont deux threads différents. Le seul moyen d'arreter X c'est qu'il décide de lui même de s'arrêter, sur base d'une information stockée dans une variable ou à la fin de son traitement.

  9. #9
    Membre averti
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    40
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 40
    Par défaut
    je suis quasiment certain que de l'extérieur il doit y avoir moyen. Mais une des conditions serait que le thread timer prenne en paramètre l'objet "this" qui lui, donnera accès à une méthode pour couper l'effet bloquant de l'objet appelant (par l'intermédiaire d'une exception ou comme tu le dit une variable spécifique à cet arrêt).

    ps: Pourquoi lancer deux thread? un seul timer suffirait.

  10. #10
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 679
    Par défaut
    je suis quasiment certain que de l'extérieur il doit y avoir moyen. Mais une des conditions serait que le thread timer prenne en paramètre l'objet "this" qui lui, donnera accès à une méthode pour couper l'effet bloquant de l'objet appelant (par l'intermédiaire d'une exception ou comme tu le dit une variable spécifique à cet arrêt).
    Non il n'y a pas de moyen direct d'interrompre un thread depuis un autre.

    C'est un problème récurent. Les commandes qui permettent de faire ça ont été dépréciées car source d'erreurs. cf http://java.sun.com/j2se/1.5.0/docs/...precation.html. La seule méthode propre de faire ça est d'utiliser une variable qui indique la demande l'interruption. Le thread a interrompre doit surveiller a intervalle régulier cette variable et s'interrompre lui même.

    Au final, implémenter ça dans son cas reviendrait donc a la même chose, en plus compliqué. Le thread devra de toute façon se surveiller lui même a intervalle régulier, qu'il surveille la date ou une demande d'interruption.

  11. #11
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par Uther Voir le message
    C'est un problème récurent. Les commandes qui permettent de faire ça ont été dépréciées car source d'erreurs. cf http://java.sun.com/j2se/1.5.0/docs/...precation.html.
    En effet en stoppant un thread depuis un autre, on peut laisser la mémoire ou le status d'objet dans un état incohérent, ce qui pourra provoquer des erreurs incompréhensible par la suite...


    Citation Envoyé par Uther Voir le message
    La seule méthode propre de faire ça est d'utiliser une variable qui indique la demande l'interruption. Le thread a interrompre doit surveiller a intervalle régulier cette variable et s'interrompre lui même.
    En général on utilise interrupt() pour cela. Certain méthode gère déjà cela mais il faut également surveiller le statut du thread (cette méthode se contente de passer une valeur "interrupted" de false à true)


    Mais pour savoir si cela peut être utilisé ou pas, il faudrait déjà savoir ce que fait le thread... (il y a certaines méthodes bloquantes qui ne gère pas du tout cela )


    a++

  12. #12
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Par défaut
    mmhh je sais pas si je je peux aider mais il se trouve que durant mon stage que je suis en train d'effectuer j'ai eu à realiser une tache similaire.
    Je vais donc poster ici un exemple de code. Mon avis est que le multi-thread permet de faire un equivalent du "timeout" :

    Multi-thread : Comment cela fonctionne t-il ?
    Il faut savoir qu’un second thread se fait donc dans une nouvelle classe qui hérite de Thread. Dans cette même classe, le code qui sera effectué en tant que sous processus se fait dans un run().
    Enfin, il ne faut pas oublier de fermer le thread qui sera appelé.

    Le code exemple de la classe principale :
    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
    public static Document reponse;
    public static long patience;
     
    private Document getTheResponse()
    throws Exception
    { 
       patience = 15000;  //Temps que vous voulez attendre
       reponse = null; //Initialisation de la variable qui sera retournée, à null	
       testThread thread = new testThread();  //Appel du second thread (je ne sais pas si dans ton cas elle est utile damien77 car moi j'y passais des variable pour un constructeur dans mon code original)
       long startTime = System.currentTimeMillis(); //On garde en variable le moment présent
       System.out.println("Veuillez patienter...");
       thread.start(); //Démarrage du second thread
       //Début de la boucle dans laquelle est appelé le code en relation avec le serveur
       while(((System.currentTimeMillis() - startTime) < patience) && (thread.isAlive()))
       { 
          if (patience == 0)
             thread.interrupt(); //Thread ne sera plus alive et donc nous sortons de la boucle
       }
       return reponse; //On retourne la variable qui nous interesse
    }


    Le code exemple du thread appelé :
    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 testThread extends Thread //Déclaration d’une nouvelle classe qui hérite de Thread
     
     
    public class testThread extends Thread{
     
       public void run() //Le code qui est inscrit dans cette procédure sera effectué comme sous-processus
       {
          try
          {
             Main.reponse = ConnexionServeur(); //reponse de la classe Main prend ce qui est retourné
             if(Main.reponse != null)
             {
                Main.patience = 0; //Patience de la classe main prend null (sortie de la boucle)
             }
             Main.patience = 0; //Patience prend 0 (on sort de la boucle dans ce cas aussi)
         }
         catch(Exception e)
         {
             System.err.println(e.getMessage()); //Affichage d’erreur
         } 
       }
    }
    J'espere que ça pourra aider

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    382
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 382
    Par défaut
    merci pour vos réponses.
    zouuc, je viens de tester ta solution mais elle ne marche pas...

  14. #14
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 679
    Par défaut
    Comme je l'ai dit utiliser un Thread est un méthode inutilement compliquée qui necessitera de toute facon de modifier la classe a interrompre.
    Pour faire au plus simple, on peut procéder ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void methodeLongue throws TimeoutException {
        final long timeout = System.currentTimeMillis() + 60000; //(60000 ms -> 1 minute)
     
        // début du code
        if( System.currentTimeMillis() > timeout ) throw new TimeoutException();
        // suite du code
    }
    Il suffit de placer la ligne qui lève l'exception de manière judicieuse dans une boucle pour que le test soit exécutée régulièrement.

  15. #15
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Par défaut
    mmhh en y reflechissant bien mon code ne correspond p-e pas à ce que tu veux faire. Dans mon cas, c'est juste que si le temps de connexion à un serveur est anormalement long (par exemple le serveur est Out ou Off) à la place d'attendre indéfiniement (ce qui se passait au début) et bien ça quitte l'appli. Dans mon cas ça marche à merveille.
    J'avais essayé de realiser ça d'une autre façon (sans appel de thread, et tout se fait dans la classe principale) et ça ne marchait pas pourtant le code était bon.
    On ne quittait jamais le while alors que pourtant ça devrait, j'ai essayé avec un multi-thread et ça à marché.

    je suis dsl que ça ne fonctionne pas damien77

  16. #16
    Membre émérite Avatar de Jidefix
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    742
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Septembre 2006
    Messages : 742
    Par défaut
    Le problème avec l'histoire de la variable et du test pour savoir si on arrête le traitement ou pas, c'est que ça ne permet pas d'arrêter le thread si celui-ci est sur une opération bloquante comme un "connect" par exemple.
    D'où l'interet du Thread.stop()
    Ils sont bien gentils de déprécier des fonctions parce qu'elles sont risquées, mais tant qu'il n'existe pas d'autre solution je dirai qu'on a pas trop le choix non?

  17. #17
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 679
    Par défaut
    zouuc> Ta méthode utilise un thread séparé et thread.interrupt() pour demander l'interruption du thread qui fait les traitements.
    Ça revient a peu près à la même chose que la variable commune dont j'avais parlé.
    La différence avec la variable commune est que certaines fonctions de Java bloquantes comme la lecture de fichier, synchronisation, ... vont lever une exception et donc se débloquer.

    Cependant interrupt() n'interromps pas directement le Thread. Il positionne juste une variable interne à true pour indiquer que le thread a demandé d'être interrompu, a la charge au programmeur de vérifier cet état et d'agir en conséquence comme le font la plupart des fonctions bloquantes de java. Le thread qui exécute l'opération longue devra donc surveiller l'état du thread via quelquechose du genre if (Thread.interrupted()) throw new TimeoutException(); exécuté a intervalle régulier.

    Donc au final le problème reviens au même qu'avec mon exemple monothread : trouver une boucle, ou le test sera effectué régulièrement.

  18. #18
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Jidefix Voir le message
    D'où l'interet du Thread.stop()
    Quel intérêt à rendre potentiellement instable une application ?

    Citation Envoyé par Jidefix Voir le message
    Ils sont bien gentils de déprécier des fonctions parce qu'elles sont risquées, mais tant qu'il n'existe pas d'autre solution je dirai qu'on a pas trop le choix non?
    Il existe d'autre solution, comme cela a déjà été indiqué dans ce post.


    Donc s'il y a toujours un problème il faudrait le spécifier avec le code qui va avec...

    a++

  19. #19
    Membre émérite Avatar de Jidefix
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    742
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Septembre 2006
    Messages : 742
    Par défaut
    Citation Envoyé par Uther Voir le message
    La différence avec la variable commune est que certaine fonctions de Java boquantes comme la lecture de fichier, synchronisation, ... vont lever une exception quand le thread est interrompu et donc ce débloquer.
    Tiens je connaissais pas ça, y-a-t-il moyen de savoir si une fonction d'une API externe sera interrompue par un "interrupt" du coup? (je veux dire, sans tester)

  20. #20
    Membre émérite Avatar de Jidefix
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    742
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations forums :
    Inscription : Septembre 2006
    Messages : 742
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Quel intérêt à rendre potentiellement instable une application ?
    Il existe d'autre solution, comme cela a déjà été indiqué dans ce post.
    Ben la seule autre solution qui semble applicable est le coup de l'interrupt, mais apparement même ça ça risque de ne pas marcher sur certaines méthodes.
    On a le probleme pour des fonctions de connexions à des serveurs via les protocoles FTP, HTTP, etc...
    Il arrive que les fonctions de login restent bloquées indéfiniment. Je ne connaissais pas le principe de l'interrupt, on va regarder si ça pourrait marcher...

Discussions similaires

  1. Créer une méthode avec string.
    Par trainingevth dans le forum C++
    Réponses: 11
    Dernier message: 13/03/2015, 14h02
  2. Réponses: 2
    Dernier message: 18/11/2011, 16h57
  3. Réponses: 1
    Dernier message: 05/10/2009, 22h13
  4. Créer une grille avec centage
    Par lil_jam63 dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 16/08/2004, 16h21
  5. [Image]Créer une image avec JAVA 1.1
    Par burno dans le forum 2D
    Réponses: 4
    Dernier message: 11/08/2004, 09h19

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