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 :

ThreadPoolExecutor - Gestion des threads ne répondant pas


Sujet :

Java

  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut ThreadPoolExecutor - Gestion des threads ne répondant pas
    Bonjour,

    Je souhaiterais savoir si il est possible de "tuer" un Thread qui ne répond pas dans un "ThreadPoolExecutor" ?

    Concrètement, je crée un pool d'éléments se connectant en IMAP, l'IMAP peut, parfois, ne pas répondre. Il me faut dans ce cas "tuer" le Thread afin qu'il puisse être réutilisé ultérieurement.

    J'ai essayé divers éléments, mais sans succès.

    Voici les différentes étapes :
    - Création :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(5);
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 5, 10, TimeUnit.SECONDS, queue);
    - Ajout dans le pool :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    threadPool.execute(agentIMAP);
    - Lorsque c'est terminé normalement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ArrayBlockingQueue<Runnable> queue2 = (ArrayBlockingQueue<Runnable>) threadPool.getQueue();
    queue2.remove(agentIMAP);
    - Tentative de "kill" manuel (qui ne fonctionne pas apparemment) :
    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
     
    // Kill du thread bloqué
    long threadID = agentIMAP.getThreadID(); //Retourne l'ID du Thread utilisé par l'agent
    Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
    Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
    for (Thread thread : threadArray)
    {
    	if (thread.getId() == threadID)
    	{
    		if (!thread.isInterrupted())
                    {
                          thread.interrupt();
    		}
    	}
    }

    Le problème est qu'avec ce type de code, lorsque l' "agentIMAP" est bloqué par l'IMAP (sur la connexion ou autre) alors le Thread attend que l'IMAP termine.

    Y-a-t-il possibilité de réellement tuer le Thread et faire que le ThreadPool le recrée ?

    Merci d'avance.

    Cordialement.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    On ne peut pas tuer un Thread, c'est à lui d'avoir des processus pour s'arrêter de lui même.

    Dans ton cas, si le Thread ne réagis pas à interrupt() (censé réveiller les appels bloquant comme le réseau) c'est cuit.

    Il faut revoir ton Thread, la manière dont tu te connecte à IMAP par exemple.

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut
    Bonjour,

    Merci pour cette réponse.

    Le problème est que je ne peux contrôler une action sur l'IMAP. J'ai beau mettre tous les timeout possibles certains IMAP ne respectent pas les timeout (pour une connexion non sécurisée) :
    - mail.imap.writetimeout
    - mail.imap.connectiontimeout
    - mail.imap.connectionpooltimeout
    - mail.imap.timeout

    La seule solution est donc d'arriver à arrêter le Thread bloqué (qui se débloque au bout de 30 à 60 minutes ...).

    Code de la connexion :
    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
     
    Properties props = System.getProperties();
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.store.protocol", "imap"); //ou "imaps"
    if (useSSL == true)
    {
    	props.put("mail.imap.class", "com.sun.mail.imap.IMAPSSLStore");
    }
    else
    {
    	props.put("mail.imap.class", "com.sun.mail.imap.IMAPStore");
    }
     
    props.put("mail.imap.writetimeout", 30000);
     
    if (useSSL == true)
    {
    	props.put("mail.imap.class", "com.sun.mail.imap.IMAPSSLStore");
    	props.put("mail.imaps.timeout", 10000);
    	props.put("mail.imaps.connectiontimeout", 10000);
    	props.put("mail.imaps.connectionpooltimeout ", 30000);
    }
    else
    {
    	props.put("mail.imap.class", "com.sun.mail.imap.IMAPStore");
    	props.put("mail.imap.timeout", 10000);
    	props.put("mail.imap.connectiontimeout", 10000);
    	props.put("mail.imap.connectionpooltimeout ", 30000);
    }
    Session session = Session.getDefaultInstance(props, null);
    URLName url = new URLName("imap" /*ou imaps*/, hostName, port, INBOX, user, password);
    IMAPStore store = new IMAPSSLStore(session, url);
    try
    {
    	store.connect();
    }
    catch (MessagingException e)
    {
    ...
    }
    catch (RuntimeException e)
    {
    ...
    }
    Les "props" ne semblent pas tous être pris en compte, notamment ceux sur le timeout.

    C'est pourquoi je souhaitais mettre en place un "manager" qui s'occupe que les Thread ne soient pas bloqué et les tuer éventuellement.

    Cordialement.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Citation Envoyé par PP(Team) Voir le message
    J'ai beau mettre tous les timeout possibles certains IMAP ne respectent pas les timeout (pour une connexion non sécurisée) :
    Ce n'est pas le serveur, mais le client qui est supposé respecter ces timeouts .
    La seule solution est donc d'arriver à arrêter le Thread bloqué (qui se débloque au bout de 30 à 60 minutes ...).
    Pas possible, point!
    Code de la connexion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (useSSL == true)
    {
    	props.put("mail.imap.class", "com.sun.mail.imap.IMAPSSLStore");
    	props.put("mail.imaps.timeout", 10000);
    	props.put("mail.imaps.connectiontimeout", 10000);
    	props.put("mail.imaps.connectionpooltimeout ", 30000);
    }
    Les docs que j'ai ne font pas mention d'un paramètre en "imaps", tu as un S en trop. Aussi, tu ne devrais pas référencer explicitement les classes en com.sun.xxxx

    La liste des properties supportées par l'implémentation imap/imaps de javamail se trouve ici:

    https://javamail.java.net/nonav/docs...e-summary.html

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Je pense que tu pourrais aussi fournir des SocketFactory custom, qui créent des sockets avec des timeout de lecture (je pense par exemple à appeler setSoTimeout sur la socket avant de la retourner)

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 585
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 585
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Les docs que j'ai ne font pas mention d'un paramètre en "imaps", tu as un S en trop.
    En fait, cette même page écrit bel et bien, en tout petit, là où personne ne le lirait d'habitude, que si on utilise le protocole imaps, il faut bel et bien remplacer les mail.imap.truc par mail.imaps.truc
    Jusqu'ici j'ai pas trop compris l'intérêt vu que j'ai pas trouvé comment utiliser plus d'un protocole avec la même conf'.

    À noter que le protocole imaps ne va pas se choisir tout seul, 'faudrait peut-être penser à l'indiquer sinon, en effet, les mail.imaps seront purement ignorés.

    Citation Envoyé par tchize_ Voir le message
    Aussi, tu ne devrais pas référencer explicitement les classes en com.sun.xxxx
    En l'occurrence ce sont des classes de la bibliothèque JavaMail, anciennement fournie par Sun, et qui ne fait pas partie de la bibliothèque Java de base.
    Y a pas le choix, les classes sont dans ce package, et elles sont de toute façon publiques et publiquement documentées avec une JavaDoc dédiée.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Je n'ai jamais eu besoin d'aller charger du com.sun explicitement pour utiliser javamail. On n'est censé utiliser que ce qui se trouve dans javax.mail. Le fait que les implémentation trainouillent dans com.sun.xxxx ne concerne pas le dev qui utilise javamail, il ne concerne que le dev qui modifie javamail.

  8. #8
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut
    Bonjour,

    J'ai enfin trouvé la solution !!!
    Lorsque je crée l'url je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //Ces données ne sont "en dur" que pour l'exemple
    String protocol = "IMAP"; //Provient en fait d'un Enum
    String hostName = "imap.qq.com" //par exemple
    int port = 143;
    String INBOX = "INBOX"
    String user = "myuser";
    String password = "mypassword";
    URLName url = new URLName(protocol, hostName, port, INBOX, user, password);
    Session session = Session.getDefaultInstance(props, null);
    Store store = new IMAPStore(session, url);
    Dans ce cas, Javamail va initialiser "SocketFetcher" (un Socketfactory) avec les timeout du type "mail.IMAP.timeout".
    Hors, je fournis "mail.imap.timeout" (normal).

    J'ai donc modifié le "protocol" fourni pour qu'il soit en minuscule et tous les problèmes sont réglés sans avoir à Surcharger le "SocketFoactory" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    String protocol = "imap"; //Provient en fait d'un Enum
    String hostName = "imap.qq.com" //par exemple
    int port = 143;
    String INBOX = "INBOX"
    String user = "myuser";
    String password = "mypassword";
    URLName url = new URLName(protocol, hostName, m_port, INBOX, user, password);
    Session session = Session.getDefaultInstance(props, null);
    Store store = new IMAPStore(session, url);
    Depuis cette modification, les timeout sont parfaitement géré par Javamail.

    Dans le genre problème qui fait perdre du temps inutilement...

    En espérant que cela puisse aider d'autres personnes.

    Merci pour votre aide.

    NB : tchize_ : pour le "s" dans les properties, si tu fournis un protocol "imaps" dans "URLName" tu dois mettre un "s" dans les properties, sinon Javamail ne reconnaitra pas les propriétés.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 483
    Par défaut
    Citation Envoyé par PP(Team) Voir le message
    Dans ce cas, Javamail va initialiser "SocketFetcher" (un Socketfactory) avec les timeout du type "mail.IMAP.timeout".
    Hors, je fournis "mail.imap.timeout" (normal).

    J'ai donc modifié le "protocol" fourni pour qu'il soit en minuscule et tous les problèmes sont réglés

    Ben j'irais me coucher moins con pour le coup, donc les properties sont pas hardcodé, elles sont concaténées au protocole demandé

    Y a des baffes qui se perdent chez oracle.

  10. #10
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut
    J'avoue que j'aurais pensé à tout sauf ça...
    Pour moi ça détectait si imap ou imaps et géré tout en dure, mais ce n'est pas le cas ....

    Sans les sources de javamail je n'aurais jamais trouvé ....

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

Discussions similaires

  1. gestion des threads
    Par yanis97 dans le forum Langage
    Réponses: 6
    Dernier message: 20/04/2006, 13h41
  2. Gestion des Threads
    Par Nalfouille dans le forum MFC
    Réponses: 3
    Dernier message: 05/04/2006, 17h29
  3. Gestion des threads
    Par yanis97 dans le forum C++
    Réponses: 6
    Dernier message: 08/03/2006, 10h39
  4. GEstion des thread
    Par Julien Dufour dans le forum Access
    Réponses: 8
    Dernier message: 06/10/2004, 15h28
  5. [reseaux] Gestion des threads en perl
    Par totox17 dans le forum Programmation et administration système
    Réponses: 2
    Dernier message: 28/11/2002, 10h40

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