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 :

Interruption et reprise d'un Thread


Sujet :

Concurrence et multi-thread Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    340
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 340
    Par défaut Interruption et reprise d'un Thread
    Voila, j'ai créé une classe qui lance, suspend et reprend un thread, via différentes méthodes.
    Voici cette classe:
    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
     
    package evolution;
     
    public class Vivre implements Runnable{
     
    	protected Thread t;
    	protected boolean encours,demarre;
    	protected Interface IHM=null;
     
    	public Vivre(Interface i){
    		encours=false;
    		demarre=false;
    		t=new Thread(this);
    		IHM=i;
     
    	}
     
    	public void Demarrer(){
    		t.start();
    		encours=true;
    	}
     
    	public void Reprendre(){
    		t.notify();
    		encours=true;
    	}
     
    	public void Suspendre() throws InterruptedException{
    		t.wait();
    		encours=false;
    	}
     
    	public synchronized void run() {
    		if(!demarre){
    			demarre=true;
    			while(IHM.grille.nbAmibe!=1){
    				try {
    					Interface.sortie.append(IHM.grille.vivre());
    					Thread.sleep(1500);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				IHM.affichageInfo();
     
    			}
    		}
    	}
     
    }
    Je manipule un objet Vivre dans le action performed de mon IHM :
    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
     
    public class Interface extends ... implements ...{
    protected Vivre v;
    public Interface(){
    v=new Vivre(this);
    [...]
    }
     
    public void actionPerformed(ActionEvent e) {
    			Object o = e.getSource();
    			/*
    			 * Action sur le bouton pour faire vivre la population
    			 */
    			if(o==boutonVie){
    				if(!v.encours){
    					if(!v.demarre) v.Demarrer();
    					else {
    						v.Reprendre();
    					}
    				} 
    				else
    				try {
    					v.Suspendre();
    				} catch (InterruptedException e1) {
    					// TODO Auto-generated catch block
    					e1.printStackTrace();
    				}
     
    			}
    [...]
    }
    }
    En l'état, lorsque je clique sur mon bouton Vivre, cela me lance bien le thread, et l'affichage de la grille avec des pauses de 1500ms.
    Mais il y a 2 problèmes :
    - lorsque j'utilisais la méthode de vie de la population, je passais directement de l'affichage de l'ancienne grille à la nouvelle grille. Or maintenant, l'affichage se fait "en direct", c'est à dire que je vois s'afficher chaque une par une, sachant que plus il y a de cases, et plus les dimensions de chacunes se réduisent, bref, c'est moche, et surtout je ne comprend pas pourquoi. Comment l'éviter???
    - le vrai problème, c'est qu'un nouveau clic sur le bouton vie ne produit rien, si ce n'est qu'une exception est levée :
    Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException: current thread not owner
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at evolution.Vivre.Suspendre(Vivre.java:28)
    at evolution.Interface.actionPerformed(Interface.java:1302)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
    Pourquoi???

  2. #2
    Membre Expert
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Par défaut
    Sans chercher trop a comprendre ton code je vois un problème majeur: wait doit se trouver dans un bloc synchronized comme décris dans la doc http://java.sun.com/j2se/1.5.0/docs/...ct.html#wait()

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    340
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 340
    Par défaut
    bon, j'ai lu l'API de la classe Object, j'ai modifié mon code en conséquence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public void Suspendre() {
    		Object o=new Object();
    		synchronized (o) {
    	         while (encours=false)
    				try {
    					o.wait();
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    	     }
    	}
    J'ai même essayer de mettre "this" comme verrou, mais rien ne change : j'ai toujours une exception " java.lang.IllegalMonitorStateException: current thread not owner " qui sort à l'appel de ma méthode reprendre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public void Reprendre(){
    		t.notify();
    		encours=true;
    	}

  4. #4
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354

  5. #5
    Membre expérimenté Avatar de jibbi
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 165
    Par défaut
    t'a essayé de placer ton synchronized dans le nom de la méthode au lieu dans un bloc;

    public synchronized void Suspendre() {}

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Février 2007
    Messages
    572
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2007
    Messages : 572
    Par défaut
    Tel que, ca ne peut pas marcher.

    L'objet de synchronisation que tu as choisi est le thread. Tu as déclaré la methode run() synchronized, le monitor est pris, et ne sera relaché que lorsque tu sortiras de la methode run() (ou si dans la methode run(), tu avais ajouté un appel à wait, mais ce n'est pas le cas ici).
    Donc meme si tu englobes tes appels a t.notify() ou t.wait() dans un bloc synchronized, tu ne pourras pas prendre le monitor, puisque la methode run() l'a pris.

    En fait, je pense plutot qu'il y a probleme de conception.

    La premiere chose, c'est d'utiliser un objet de synchronisation qui ne soit pas le thread. Typiquement, ca peut être un attribut du genre
    Object lock = new Object();
    Il est techniquement possible d'utiliser thread comme objet de synchronisation, mais je trouve ca beaucoup moins clair.

    Ensuite, il faut gerer la suspension et la reprise dans la methode run() de ton thread. Typiquement, il faut quelque chose du genre

    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
    public void run() {
          while (true) {
                 synchronized (lock) {
                      if (!en_attente) 
                         lock.wait(1500);
                     if (stop_thread)
                         break;
                     if (en_attente)
                        lock.wait();
                     if (stop_thread)
                         break;
                 }
                 ...
                 mon_code();
                 ...
          }
    }
    Et pour les methodes pour suspendre et reprendre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public void suspendre() {
       synchronized(lock) {
           en_attente = true;       
       }
    }
     
     
    public void rependre() {
       synchronized(lock) {
           en_attente = false;       
           lock.notify();
       }
    }

Discussions similaires

  1. interruption et reprise d'un thread
    Par Virgile le chat dans le forum Concurrence et multi-thread
    Réponses: 4
    Dernier message: 09/07/2007, 13h28
  2. arret et reprise d'un thread
    Par voyageur dans le forum Windows Forms
    Réponses: 13
    Dernier message: 09/04/2007, 10h39
  3. Interruption et reprise d'un Thread
    Par Nuro dans le forum Concurrence et multi-thread
    Réponses: 1
    Dernier message: 28/02/2007, 21h34
  4. pause et reprise de thread
    Par raggadoll dans le forum C++Builder
    Réponses: 5
    Dernier message: 12/07/2003, 10h50
  5. Pause et reprise d'un thread
    Par raggadoll dans le forum Linux
    Réponses: 5
    Dernier message: 03/07/2003, 20h22

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