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 :

Threads synchronisés ?


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Décembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 33
    Par défaut Threads synchronisés ?
    Hello
    Voilà j'essaie de faire un programme avec 2 threads et j'ai beaucoup de mal à comprendre comment les faire communiquer.

    En gros j'ai un thread 1 de calcul dont la méthode run() consiste a calculer un tableau et à la stocker quelque part. L'opération prend en gros 10 ms.

    En parralèle j'ai un thread 2 d'affichage qui se charge d'afficher les données d'un tableau toutes les 10 ms et qui le fait 10 fois avant de le faire sur le tableau suivant. L'opération sur un tableau donné me prend donc 100 ms.

    Bref je voudrais que mon thread 1 se bloque quand il a fini de calculer, et que le thread 2 puisse le relancer quand l'affichage est fini (itération d'apres)
    De meme, il faudrait que le thread 2 puisse se bloquer et attendre que le thread 1 ait fini de calculer dans le cas rare où le thread 1 aurait été lent.


    On m'a dit d'utiliser un objet fictif que je nomme lock et d'utiliser lock.wait() et lock.notifyAll() depuis mes threads.

    Bon apres testage ça marche pas... je me prend un IllegalMonitorStateException.
    Ce que j'ai fait :
    - mettre public static final Object lock = new Object(); dans la classe qui contient le main
    - appeller lock.wait() ou lock.notifyAll() depuis mes threads créés depuis le main.

    Comment corriger ça ?

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    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 482
    Par défaut
    tu ne peux appeler les méthodes de lock que dans un bloc synchronizé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    synchronized(lock) {
        lock.wait();
    }

    sinon, pour ton besoin, regarde du coté des synchronized queues java. Ton thread de calcul aura juste à lire une queue de demandes et écrire dans une queue de réponses.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 138
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    sinon, pour ton besoin, regarde du coté des synchronized queues java. Ton thread de calcul aura juste à lire une queue de demandes et écrire dans une queue de réponses.
    Tout à fait, depuis java 5, il y a des classes qui aident à la programmation parallèle.
    Regarde la classe BlockingQueue , elle est spécialement faite pour tout ce qui est producteur-consommateur.
    C'est beaucoup plus élégant que d'utiliser des locks, wait et notify qui sont des techniques plus bas niveau, ceci dit dans un but pédagogique c'est intéressant.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 138
    Par défaut
    http://java.sun.com/j2se/1.5.0/docs/...kingQueue.html

    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
     
     class Producer implements Runnable {
       private final BlockingQueue queue;
       Producer(BlockingQueue q) { queue = q; }
       public void run() {
         try {
           while(true) { queue.put(produce()); }
         } catch (InterruptedException ex) { ... handle ...}
       }
       Object produce() { ... }
     }
     
     class Consumer implements Runnable {
       private final BlockingQueue queue;
       Consumer(BlockingQueue q) { queue = q; }
       public void run() {
         try {
           while(true) { consume(queue.take()); }
         } catch (InterruptedException ex) { ... handle ...}
       }
       void consume(Object x) { ... }
     }
     
     class Setup {
       void main() {
         BlockingQueue q = new SomeQueueImplementation();
         Producer p = new Producer(q);
         Consumer c1 = new Consumer(q);
         Consumer c2 = new Consumer(q);
         new Thread(p).start();
         new Thread(c1).start();
         new Thread(c2).start();
       }
     }

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 121
    Par défaut
    lock.notifyAll() sert a prévenir les autres Thread qui attendent ce lock que tu vas le libérer
    Celà n'a de sens que si ton instruction est sous le controle de ce lock c.à.d. dans un block d'instructions synchronized(lock){...}.
    lock.wait() sert à mettre le Thread en cours en attente de ce lock et à rendre disponible ce lock au premier Thread qui mettra la main dessus.

    Voici un petit exemple de bascule entre 2 Threads:
    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
     
    public class TestThreads {
     
    	public Thread a = new A();
    	public Thread b = new B();
    	public Object lock = new Object();
     
    	class A extends Thread {
     
    		public void run() {
     
    			synchronized (lock) {
    				System.out.println("A démarre et prend le lock ...");
    				/*
    				 * A demarre B
    				 */
    				b.start();
     
    				while (b.isAlive()) { 
    					try {
    						System.out.println("A est en action...");
    						sleep(200);
    						lock.notifyAll();
    						lock.wait();
    					} catch (InterruptedException e) {
    						System.out.println("A a été interrompu par un autre Thread");
    						break;
    					}
    				}
     
    				lock.notifyAll(); // Notifier ...Je n'ai plus besoin du lock 
    			}
     
    			System.out.println("A STOP");
    		}
    	}
     
    	class B extends Thread {
     
    		public void run() {
    			try {
    				synchronized (lock) {
     
    					System.out.println("B démarre et prend le lock ...");
     
    					for (int i = 0; i < 10; i++) {
    						System.out.println("B est en action "+(i+1)+"e X ...");
    						sleep(100);
    						lock.notifyAll();
    						lock.wait();
    					}
     
    					lock.notifyAll(); // Notifier ...Je n'ai plus besoin du lock 
    				}
     
    			} catch (InterruptedException e) {
    				System.out.println("B a été interrompu par un autre Thread");
    			}
     
    			System.out.println("B STOP");
    		}
     
    	}
     
    	public static void main(String[] args) {
    		TestThreads test = new TestThreads();
    		test.a.start();
    	}
     
    }

  6. #6
    Membre Expert
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 047
    Par défaut
    Le plus simple, c'est d'utiliser les conditions et signaux.

    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
     
    // pseudo code
    Thread1 {
       for ever() {
          Thread1.condition.await()
          computeArray();
          Thread2.condition.signal();
       }
    }
     
    Thread2 {
       for ever() {
          Thread2.condition.await()
          displayArray();
          Thread1.condition.signal();
       }
    }

Discussions similaires

  1. Threads non synchronisés avec le Blender Game Engine
    Par -Sly- dans le forum Général Python
    Réponses: 0
    Dernier message: 21/11/2009, 19h18
  2. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  3. Programmer des threads
    Par haypo dans le forum C
    Réponses: 6
    Dernier message: 02/07/2002, 13h53
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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