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 :

Comment Forcer le Kill d'un thread


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2003
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 36
    Par défaut Comment Forcer le Kill d'un thread
    Bonjour,

    Je ne trouve pas le moyen de détruire un thread sans utiliser de méthodes deprecated du style Beaucoup de sites conseillent d'utiliser un boolean qui determine l'etat du thread ... par exemple comme ci dessous décrit dans la FAQ Java de developpez.com :

    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
     
    private boolean stopThread = false;
     
    public void run() {
            boolean fin = false;
     
            while( !fin ) {
                    try {
                            // traitement
     
                            synchronized(this) {
                                    Thead.yield();
     
                                    // lecture du boolean 
                                    fin = this.stopThread;
                            } 
                    } catch( InterruptedException e ) {
     
                    } 
            } 
    } 
     
    public synchronized void stop() {
            this.stopThread = true;
    }
    Mais ma problématique est que j'utilise une methode qui dure environ 2 minutes.
    J'aimerai pouvoir Forcer la destruction du thread pendant que cette méthode est entrain de s'executer.
    Voici le code de ma méthode en question ( C'est une insertion de données en base) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ...
    stmt.execute("LOAD DATA INFILE 'datainsert.csv' INTO TABLE t_ma_table FIELDS TERMINATED BY ';';");
    ...
    Quelqu'un pourrait t'il me dire comment forcer le kill d'un thread en execution?

    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
    Par défaut
    Le seul moyen fiable de killer un Thread récalcitrant est de terminer le Thread principal de l'application. Il n'existe aucun autre moyen à ma connaissance de forcer l'arrêt d'un Thread.

    Et encore, même en terminant le Thread principal, il y a certaines conditions à remplir. On a en fait deux choix :
    1) Stopper la jvm avec System.exit(), ce qui a pour effet de killer tous les Thread.
    2) Définir le Thread à killer comme demon (Thread.setDaemon(true)). Le démon se terminera lorsqu'il ne restera que des démons. C'est-à-dire, si aucun autre Thread n'a été lancé, lorsque le Thread principal se terminera.

    En conséquence, pour killer à coup sûr un Thread, il faut stopper l'application.

    Une solution est de lancer le Thread à killer dans une instance spécifique de la jvm. Le problème est qu'une application java ne peut pas lancer directement une autre application java. Il faut passer par un bootstrap de type .bat ou .sh.

  3. #3
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : R&D - Palefrenier programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 096
    Par défaut
    Dans mes souvenir j'avais un truc similaire qui exécutait une requête SQL, qui si celle ci dépassait 500 ms devait se terminer et éventuellement recommencer.

    Le execute requête étant bloquant, je l'avais mis dans un thread que j'interrompais salement avec :

    et ca fonctionnait (par chance sans doute...),
    le stmt.execute était interrompus presque illico, maintenant ce n'est surement pas le mieux a faire mais je ne vois pas comment faire autrement...

    Sinon après une petite recherche je suis tombé la dessus, je ne sais ce que ca vaut : http://onjava.com/pub/a/onjava/2004/06/16/dbcancel.html
    ou alors ceci avec on dirait, un truc tout fait https://www.securecoding.cert.org/co...+be+terminated
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    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 wax78 Voir le message
    le stmt.execute était interrompus presque illico, maintenant ce n'est surement pas le mieux a faire mais je ne vois pas comment faire autrement...
    L'appel à interrupt() est la meilleure solution ! Je ne vois pas en quoi ce ne serait pas propre !


    Le stop() est à éviter comme la peste car il arrête brutalement le thread, en laissant tout en l'état. Du coup on peut se retrouver avec des données en mémoire incohérente ou des ressources bloquées...

    Avec interrupt() on se contenter de demander au thread de bien vouloir s'arrêter. En gérant cela correctement on peut donc libérer tout ce qu'il faut et rendre la main dès que possible...


    Maintenant la seule contrainte c'est que les méthodes bloquantes doivent gérer cela, ce dans le cas présent cela doit dépendre du driver JDBC...

    Mais s'il ne gère pas cela, il n'y a pas vraiment de solution propre pour arrêter le thread (à moins d'arrêter carrément le programme).


    a++

    [edit] @wax78 : pour un timeout on peut utiliser directement la méthode setQueryTimeout()

  5. #5
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 096
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : R&D - Palefrenier programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 096
    Par défaut
    Bah oui j'ai dit sale pour être sure de ne pas me faire trop démontés si c'était pas bon

    Je pense qu'avec le connecteur Oracle (testé a l'époque) l'interrupt passait bien, pour avoir.

    Sinon bien vu pour le timeout ca peut toujours servir.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2003
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 36
    Par défaut
    Je vous remercie pour vos réponses.

    J'utilise le stop actuellement car j'ai tenté le interrupt() mais cela ne fonctionne pas.

    J'ai fait par exemple un petit script pour tester ci dessous et le thread manifestement ne s'arrete pas, dans l'exemple l'execution devrait s'arreter des que (ou preske...) le compteur du Main atteint 4000 mais le thread continue son execution jusqu'a la fin (cpt = 50000 ds l'exemple)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public static void main(String[] args) {
     
    	Thread t = new Thread(new UpdateProcess("toto.zip"));
    	t.start();
    	int cpt = 0;
    	while (true) {
    		System.err.println("Main : " + cpt);
    		cpt++;
    		if (cpt == 4000)
    			t.interrupt();
    		if (cpt == 30000)
    			break;
    	}
    et mon thread :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class UpdateProcess implements Runnable {
    ...
    public void run() {
    	int cpt = 0;
    	while (true) {
    		cpt++;
    		System.out.println("Run :"+cpt);
    		if (cpt == 50000)
    		break;
    	}
    }
    ...
    Qqchose m'a échappé ?

    Merci

Discussions similaires

  1. Réponses: 6
    Dernier message: 15/11/2007, 12h31
  2. Réponses: 4
    Dernier message: 13/06/2007, 15h27
  3. [Sql] Comment forcer un Accent-Insensitive ?
    Par manu59 dans le forum DB2
    Réponses: 2
    Dernier message: 23/08/2005, 13h39
  4. [Struts]comment forcer un Forward ?
    Par njac dans le forum Struts 1
    Réponses: 4
    Dernier message: 13/10/2004, 15h02

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