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 :

problème avec wait() pour un thread


Sujet :

Java

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 10
    Points : 6
    Points
    6
    Par défaut problème avec wait() pour un thread
    Bonjour à tous,

    J'ai un petit problème avec mon logiciel. J'ai developpé une IHM qui visualise en temps réel des aéronefs. J'ai un thread qui lit les données des aéronefs et mon "main" qui lance mon IHM. Je voudrais pouvoir ajouter une fonction pause à mon IHM c'est à dire lorsque je clique sur ce bouton, le thread qui lit les données des aéronefs se met en pause. J'ai donc fait un wait() sur ce thread, mais le probleme c'est que tout se bloque ! je ne peux plus rien toucher sur l'appli. je vous montre quelques bouts de code pour mieux comprendre :


    public class LuciadDataModelLoopThread extends DataModelLoopThread {

    public LuciadDataModelLoopThread(DataModelLoop genLoop)
    {
    super (genLoop);
    }

    public void run()
    {
    try{
    while (LuciadMain.getVisualisation() == false)
    {
    sleep(1);
    }

    }catch (Exception e) {
    System.out.println("erreur: " + e.getMessage());
    }
    super.run ();

    }
    }



    public class FileMain {



    public static void main(String[] args) {

    try {

    /...../

    FlightModel model = new FlightModel ();

    FileDataModelLoop loop = new FileDataModelLoop (model, dataFile);
    loop.setSpeedFactor (speedFactor);
    LuciadDataModelLoopThread thread=new LuciadDataModelLoopThread(loop);
    LuciadMain main = new LuciadMain (loop, thread);


    main.run (args, thread);


    } catch (IOException ioe) {
    System.err.println ("Can't create default configuration " + Configuration.getDefaultConfiguration ());
    ioe.printStackTrace ();
    }

    }

    }

    public class LuciadMain extends AbstractMain{

    public LuciadMain(DataModelLoop loop, Thread _thread)
    {
    super(loop);
    //try { java.lang.Thread.sleep(2000); } catch (java.lang.Exception e) { System.out.println("Exception in sleep : " + e); }
    System.out.println("LuciadMain constructor");
    trackModel=new TrackModel(new TLcdLonLatBounds( 35, 40, 35, 30 ));
    cometModel=new CometModel(new TLcdLonLatBounds( 35, 40, 35, 30 ));
    speedVectorModel=new SpeedVectorModel(new TLcdLonLatBounds( 35, 40, 35, 30 ));
    /*HmiController*/ controller = new HmiController (trackModel, cometModel, speedVectorModel); //controleur doit etre global et static
    addObserver (controller);
    this.thread=_thread;



    }

    protected void createAndShowGui ()
    {

    System.out.println("createAndShowGui");

    frame=new JFrame("IESTA - Fédéré de Visualisation 2D");
    //add panelFreeze

    panelFreeze=new PanelFreeze(thread);
    frame.add(panelFreeze,BorderLayout.SOUTH);

    frame.setVisible(true);





    /..../

    visualisation=true;
    }


    }

    public class PanelFreeze extends JPanel{

    private JToggleButton buttonPause;
    private JSlider sliderTime;
    private final Thread thread;


    public JToggleButton getButtonPause()
    {
    return buttonPause;
    }

    public PanelFreeze(Thread _thread)
    {
    this.thread=_thread;
    this.setPreferredSize(new Dimension(1200,35));
    this.setVisible(true);
    this.setLayout(new BorderLayout());
    JToolBar toolBar = new JToolBar();
    this.add(toolBar, BorderLayout.WEST);
    toolBar.setOrientation(toolBar.HORIZONTAL);

    buttonPause=new JToggleButton("Pause",false);
    buttonPause.setBorderPainted(true);
    toolBar.add(buttonPause);

    buttonPause.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent ev) {

    pauseThread(thread);

    }
    });



    sliderTime= new JSlider();
    this.add(sliderTime);



    }

    public void pauseThread(Thread _thread) {
    synchronized (_thread) {
    while (buttonPause.isSelected())
    try {
    _thread.wait();
    } catch (InterruptedException exc) {
    System.out.println("Erreur = " + exc.getMessage());
    }

    }

    }
    }



    Bon j'ai essayé de raccourcir au maximum. Donc la classe LuciadDataModelLoopThread est bien le thread que je veux mettre en pause. Je vous demande si vous avez une idée du pourquoi ça me bloque tout quand j'appuie sur ce fichue bouton.

  2. #2
    Membre éclairé
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Points : 844
    Points
    844
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public void pauseThread(Thread _thread) {
    synchronized (_thread) {
    while (buttonPause.isSelected())
    try {
    _thread.wait();
    } catch (InterruptedException exc) {
    System.out.println("Erreur = " + exc.getMessage());
    }
     
    }
    La ligne _thread.wait(); ne met pas en pause le thread "_thread" mais le thread courant qui est en attente d'un notify sur le monitor (lock) obtenu auprès de l'objet "_thread". Dans ton cas _thread n'est que l'objet servant à effectuer la synchronisation. Et le thread courant c'est l'EventDispachThread (le thread graphique levant l'evenement d'appui sur le bouton).


    Typiquement, ton thread à bloquer pourrait ressembler à ceci:
    (je n'ai pas mis les try/catchs etc.. pour une meilleur lisibilité)

    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
     
        private boolean running = true;
        private boolean paused = false;
        private final Object LOCK = new Object();
     
        public void run() {
           running = true;
           while( running ) {
              synchronized( LOCK ) {
                    if( paused ) LOCK.wait();
              } 
              // Raffraichissement loop
           }
        }
     
        public void setPause(boolean value) {
             synchronized(LOCK) {
                  if( value == paused ) return;
     
                  paused = value;
                  if( !paused ) LOCK.notifyAll();
            }
        }
     
        public void stop() {
                running = false;
                setPause(false);
        }
    Dans ton programme graphique, il te suffit d'appeler le setPause()
    JBusyComponent, une API pour rendre occupé un composant swing.
    SCJP Java 6.0 (90% pass score)

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    ok mais alors je ne comprend pas le "private final Object LOCK = new Object();" Dois-je utiliser cet objet tel quel ? j'ai du mal a comprendre a quoi il sert ici.
    Donc tu pense que si je rajoutes ton code dans la methode run de la classe LuciadDataModelLoopThread, cela fonctionnera ?

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    alors j'ai fait ce que tu m'as dit mais en fait je vois que ça ne peut pas fonctionner car dans mon run () je fais appel a la methode genLoop.start (); qui commence la lecture du fichier d'aéronef.... et lorsque je commence cette méthode elle n'est jamais interrompu jusqu'a la fin...

    je te montre ce que j'ai ecrit :

    public class DataModelLoopThread extends Thread {

    private DataModelLoop genLoop;
    private boolean paused = false;
    private boolean running = true;
    private final Object lock = new Object();

    public DataModelLoopThread (DataModelLoop genLoop) {
    this.genLoop = genLoop;

    }

    public void setPause(boolean value) {
    synchronized(lock) {
    if( value == paused ) return;

    paused = value;
    if( !paused ) lock.notifyAll();
    }
    }

    public void stopp() {
    running = false;
    setPause(false);
    }


    public void run () {
    try {
    running = true;
    while (running) {
    synchronized (lock) {
    System.out.println("1111111111111111111111111");
    if (paused)
    lock.wait();
    }
    genLoop.start ();

    }
    } catch (InterruptedException exc) {
    System.out.println("Erreur = " + exc.getMessage());
    }



    }
    }



    public class PanelFreeze extends JPanel{

    private JToggleButton buttonPause;
    private JSlider sliderTime;
    private LuciadDataModelLoopThread threadLoop;
    private boolean flagPause=false;

    public boolean getFlagPause()
    {
    return flagPause;
    }


    public JToggleButton getButtonPause()
    {
    return buttonPause;
    }

    public PanelFreeze(LuciadDataModelLoopThread _threadLoop)
    {
    this.threadLoop=_threadLoop;
    this.setPreferredSize(new Dimension(1200,35));
    this.setVisible(true);
    this.setLayout(new BorderLayout());
    JToolBar toolBar = new JToolBar();
    this.add(toolBar, BorderLayout.WEST);
    toolBar.setOrientation(toolBar.HORIZONTAL);

    buttonPause=new JToggleButton("Pause",false);
    buttonPause.setBorderPainted(true);
    toolBar.add(buttonPause);

    buttonPause.addActionListener(new ActionListener()
    {
    public void actionPerformed(ActionEvent ev) {

    pauseThread(threadLoop);

    }
    });



    sliderTime= new JSlider();
    this.add(sliderTime);



    }

    public void pauseThread(LuciadDataModelLoopThread _threadLoop) {

    if(buttonPause.isSelected())
    {
    _threadLoop.setPause(true);
    }
    else
    {
    _threadLoop.stopp();
    }



    }
    }


    je ne sais pas comment faire pour arreter mon thread au final. Il faut carrement que j'aille dans la partie lecture du fichier.... nan ?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    Bon ça y est j'ai trouvé une solution. Je fais tout directement dans ma boucle de lecture de fichier. Merci pour vos conseils.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 20/04/2009, 10h49
  2. Petit problème avec GCC pour l'Unicode...
    Par Nico*3-3 dans le forum Autres éditeurs
    Réponses: 6
    Dernier message: 29/01/2006, 17h12
  3. problème avec strtok pour récupérer les vides
    Par manikou dans le forum MFC
    Réponses: 4
    Dernier message: 02/06/2005, 20h08
  4. Réponses: 5
    Dernier message: 27/08/2003, 11h45

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