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 :

Thread wait ou sleep ?


Sujet :

Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2007
    Messages : 165
    Points : 73
    Points
    73
    Par défaut Thread wait ou sleep ?
    Bonjour,

    Mon application a 2 Thread majeur :
    - Le GUI
    - Le Thread qui s'occupe des transferts de données réseaux

    A un moment la personne appuiera sur un bouton pour faire une demande de données et donc si je ne fais rien, le Thread GUI essaie de récupérer la variable trop vite et donc récupère du null.
    Ma question est la suivante :
    Quelle est la meilleure solution pour faire qu'un Thread attende sur un autre ?
    J'ai essayé sleep, marche très bien mais je ne peux pas savoir le nombre de temps que le transfert va prendre donc c'est un peu hasardeux.
    J'ai essayé wait mais il me met une erreur sûrement dû à la synchronisation des Thread.
    Que me conseillez-vous de faire ?

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at unoclient.viewTable.loadingList(viewTable.java:57)
    at unoclient.viewTable.jButtonRefreshActionPerformed(viewTable.java:205)
    at unoclient.viewTable.access$000(viewTable.java:25)
    at unoclient.viewTable$2.actionPerformed(viewTable.java:187)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6263)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
    at java.awt.Component.processEvent(Component.java:6028)
    at java.awt.Container.processEvent(Container.java:2041)
    at java.awt.Component.dispatchEventImpl(Component.java:4630)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
    at java.awt.Container.dispatchEventImpl(Container.java:2085)
    at java.awt.Window.dispatchEventImpl(Window.java:2478)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
    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
    public void  loadingList() throws InterruptedException, IOException{
            this.client.getData().wait();    <---------- Erreur
            jButtonRefresh.setEnabled(false);
            DefaultTableModel model = new DefaultTableModel(
                    new Object[4][],
                new String [] {
                    "Name", "Type", "Slots", "Room leader"
                });
     
            jLabelTable.setText("Loading...");
            jTableGamesList.setModel(model);
            jLabelGamesFound.setText("Searching for games.");
            this.client.getData().notify();
            Thread.currentThread().wait();
            getNetwork().writeObject(new cmdToServer().playerRefreshTables(getPlayer()));
            setGames(this.client.getGames());
    Thread.currentThread().notify();
     
        }
    Cordialement,

    rXp>!<

  2. #2
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    La wait() est une mécanisme de synchronisation qui nécessite un bloc synchronized.

    Mais ce n'est pas vraiment la solution dans ton cas. Si tu fais cela dans le thread de l'UI, tu vas bloquer ton interface graphique.

    Il est préférable d'utiliser un SwingWorker pour cela. La méthode doInBackground() sera exécutée dans un thread en tâche de fond, et la méthode done() sera exécutée à le fin dans l'EDT afin de permettre le rafraichissement de la GUI...


    a++

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2007
    Messages : 165
    Points : 73
    Points
    73
    Par défaut
    Merci pour ta réponse je vois bien que c'est ce que je fois faire.
    Dans les exemple que j'ai trouver ils exécutent le SW au début, mais ai-je le droit de le lancer quand j'ai envie ? (en mettant l'objet swingworker disponible à tous).

    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 viewTable(Game[]games2, Player player2, Network net2, Client client2) {
            try {
                initComponents();
                jLabelTable.setText("Loading...");
                this.setVisible(true);
                games = games2;
                player = player2;
                network = new Network(net2);
                client = client2;
                swingWorker.doInBackground();
            } catch (Exception ex) {
                Logger.getLogger(viewTable.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    [EDIT]
    Merci beaucoup j'ai réussi
    Pour ceux que cela intéresse voici le code de SwingWorker :
    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 static void main(String args[], final Game[] rooms2, final Player player2, final Network net2, final Client client2) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    viewTable gui = new viewTable(rooms2, player2, net2, client2);
                    swingWorker = gui.new SwingW();
                    swingWorker.execute();
                }
            });
        }
     
        class SwingW extends SwingWorker<Integer, String> {
     
            public SwingW() {
            }
     
            @Override
            protected void done() {
                try {
                    refreshTables();
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
     
            @Override
            protected Integer doInBackground() throws Exception {
                loadingList();
                return 1;
            }
     
     
        }
    Et a chaque fois que j'utilise SwingWorker j'en crée un nouveau et l'exécute. Est-ce correct ?

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

Discussions similaires

  1. Problème de thread: isAlive when sleeping ?
    Par minimarch76 dans le forum Concurrence et multi-thread
    Réponses: 5
    Dernier message: 01/04/2008, 22h46
  2. [THREAD]wait() sur un processus autre que celui courant
    Par GesMo dans le forum Concurrence et multi-thread
    Réponses: 1
    Dernier message: 20/03/2008, 11h50
  3. Wait ou Sleep ?
    Par Mzr dans le forum C++Builder
    Réponses: 9
    Dernier message: 18/12/2006, 21h39
  4. [débutant][Thread] wait et NotifyAll
    Par norkius dans le forum Concurrence et multi-thread
    Réponses: 2
    Dernier message: 14/03/2005, 15h28

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