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

Concurrence et multi-thread Java Discussion :

Stopper thread Executor Service


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 153
    Points : 50
    Points
    50
    Par défaut Stopper thread Executor Service
    Bonjour,

    J'ai un problème pour stopper une tâche qui est exécutée par un ExecutorService.
    Je garde en mémoire le "Future" que doit me retourner la méthode call de la classe implémentant Callable et j'appelle cancel(true) dessus.

    Le problème est que mon thread lié à la tache ne stoppe pas.
    Sachant que je souhaiterai éviter d'attendre qu'un traitement dans le thread soit fini pour checker si le booleen isInterrupted est true ou pas.

    Voici la méthode call :
    Pour le moment j'ai juste mis la vérif du booléen dans la grande boucle mais je vais surement devoir le vérifier ailleurs non ? Que se passe t'il si on souhaite stopper une tâche en plein milieu d'un traitement, y a t'il une exception de levée ?

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    @Override
    	public Boolean call() throws Exception {
    		System.out.println("Thread " + Thread.currentThread().getId());
     
    			Iterator<IStep> it = run.getSteps();
    			IStep lastRepFwdStep = run.getLastStepRepFwd();
     
    			IStep step = null;
    			if (debut != null) {
    				while (it.hasNext()) {
    					step = (IStep) it.next();
    					if (step.getName().equals(debut)) {
    						break;
    					}
    				}
    			}
     
    			while (it.hasNext() && !isEnd && !Thread.currentThread().isInterrupted()) {
    				// Si pas de début spécifié ou que le debut demandé a été
    				// exécuté on
    				// passe à l'étape suivante
    				if (debut == null || debutExec) {
    					step = (IStep) it.next();
    				}
    				if (step.getName().equals(fin)) {
    					isEnd = true;
    				}
    				currentStep = step;
    				// notifyObservers();
    				// On met a true pour dire que l'étape debut demandé va être
    				// exécuté, on pourra passer au suivante apres
    				debutExec = true;
    				if (((Step) step).getType().equals("fwd")) {
    					StepForward stf = (StepForward) step;
     
    					while (q.isEmpty()) {
    						//Thread.sleep(100);
    						// System.out.println("Attente qu'un message arrive dans le superviseur...");
    					}
    					System.out.println("Message arrivé");
    					stf.setMessage(q.poll());
    					stf.setDestinataire(destinataire);
    					IdataRetour data = stf.runStep();
    					list_dataPost = stf.getListData();
     
    					System.out.println("Retour de l'étape " + step.getName()
    							+ " : " + data.getMessage());
    					System.out.println("Queue réponse avant : " + qRep.size());
    					qRep.add(data.getMessage());
    					System.out.println("Queue réponse après : " + qRep.size());
     
    				} else if (((Step) step).getType().equals("rep")) {
    					messArenvoyer = null;
    					if (!qRep.isEmpty()) {
    						messArenvoyer = qRep.poll();
    					}
     
    					System.out.println("Réponse : " + step.getName()
    							+ messArenvoyer);
     
    					if (lastRepFwdStep != null
    							&& lastRepFwdStep.getName().equals(step.getName())) {
    						System.out
    								.println("On notifie que c'est la dernière étape");
    						notifyLastStep();
    					}
    					notifyObservers();
    				} else {
     
    					step.setDataPost(list_dataPost);
    					IdataRetour retour_data = step.runStep();
     
    					System.out.println("Retour de l'étape " + step.getName()
    							+ " : " + retour_data.getCode());
    				}
    			}
    			System.out.println("Fini par interruption : "+Thread.currentThread().isInterrupted());
     
    		Proxy.hotBilling = false;
    		majTablesProxy();
    		return true;
    	}

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Hello,

    Citation Envoyé par flolebreton Voir le message
    Que se passe t'il si on souhaite stopper une tâche en plein milieu d'un traitement, y a t'il une exception de levée ?
    Cela dépend où en est l'exécution au moment de l'interruption.
    - Si elle est bloquée dans un appel read() ou write() d'IO bloquante qui gère les interruptions, l'appel est annulé avec InterruptedIOException.

    - Si elle est bloquée dans une attente de genre wait(), join() or sleep(), l'attente est annulée avec InterruptedException.

    - Si elle est en plein calculs sans aucun point bloquant, genre une boucle de calcul des décimales de pi, l'exécution continue comme avant sans que ça change quelque chose. Mais le thread porte désormais le flag "interrompu" de sorte que le prochain appel à isInterrupted() renvoie true. Ou que le prochain appel bloquant qui doive lever une exception d'interruption, lève cette exception d'interruption.

    - Si elle est dans un état bloquant qui ne gère pas les interruptions (par exemple en plein read()/write() sur une Socket naturelle,) c'est comme si elle était en plein calcul non-bloquant. L'interruption n'est pas gérée et il va falloir attendre la fin de l'appel bloquant.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2006
    Messages : 70
    Points : 218
    Points
    218
    Par défaut
    Et pour préciser sur le point 3 de thelvin, à savoir comment détecté si le thread courant a été annulé (ou plutôt, si une demande d'annulation à été effectué), voilà comment faire.

    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Thread currentThread = Thread.currentThread();
     
    if( currentThread.isInterrupted() ) {
         return; // ou tout autre code pour quitter la tache en cours
    }

    Que le code soit exécuté dnas une boucle ou non, il est peut être nécessairement de faire le test à plusieurs endroit dans le thread.

    De même, si tu développe une méthode bloquante, tu peux, à la place d'un "return" lever toi même une exception de type InterruptedException.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 153
    Points : 50
    Points
    50
    Par défaut
    Merci pour vos réponses !

    Par contre si on part du principe que ma méthode runStep() peut être plus ou moins longue et qu'elle génère aucune exception pouvant être catchée ou quoi que ce soit, comment faire pour l'interrompre ?

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Il faut qu'elle vérifie isInterrupted() de-ci de-là entre les étapes plus ou moins longues, et lance une InterruptedException si ça renvoie true.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 153
    Points : 50
    Points
    50
    Par défaut
    Voilà ma méthode runStep

    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
    @Override
    	public IdataRetour runStep() throws InterruptedException{
    		se.chargerScript(donnee);
     
    		List<Object> liste_parametres=new ArrayList<Object>();
    		// On donne les paramètres ENVIRONNEMENT, RUN
    		liste_parametres.add(r.getEnv().getName());
    		liste_parametres.add(r.getName());
    		liste_parametres.add(r.getRunType());
     
    		for(Argument arg : args){
    			liste_parametres.add(arg.getValue());
    		}
     
    		//Pour proto HOT Billing avec passage du numéro de compte
    		if(list_dataPost.size()>0){
    			DataPost firstElement=list_dataPost.get(0);
    			liste_parametres.add(firstElement.getParameterValue());
    		}
     
    		int res = se.runScript(liste_parametres);
    		IdataRetour d = new DataRetour(res);
    		return d;
    	}
    Et la méthode runScript :

    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
    @Override
    	public int runScript(List<Object> params) {
     
    		PyString[] argArray=new PyString[params.size()];
    			argArray=new PyString[params.size()];
    			for(int i=0;i<params.size();i++){
    				String value=(String) params.get(i);
    				PyString arg=new PyString(value);
    				argArray[i]=arg;
    			}
     
    		PyObject result = someFunc.__call__(argArray);
    		System.out.println("pyObject is null : "+ result==null);
    		Integer realResult = (Integer) result.__tojava__(Integer.class);
     
    		return realResult;
    	}
    J'ai du mal à voir comment je peux checker isInterrupted et renvoyer une interruptedException parce que si mon appel à __tojava __ de l'api jython appelle une boucle infini en python, bah ca va rester bloquer sur la méthode.

Discussions similaires

  1. [Thread] Executor et timeout
    Par BiM dans le forum Général Java
    Réponses: 28
    Dernier message: 21/09/2012, 14h49
  2. thread timer service
    Par Pymento dans le forum Général Python
    Réponses: 6
    Dernier message: 25/02/2010, 13h08
  3. Thread et Service
    Par ndruet dans le forum Android
    Réponses: 9
    Dernier message: 08/02/2010, 14h28
  4. [WD12] Timer, Thread ou service ?
    Par bruce207 dans le forum WinDev
    Réponses: 3
    Dernier message: 06/01/2010, 11h56
  5. Problème pour stopper thread avec runnable
    Par fabou3377 dans le forum Concurrence et multi-thread
    Réponses: 3
    Dernier message: 13/03/2008, 13h43

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