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

avec Java Discussion :

Compréhension des Threads


Sujet :

avec Java

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut Compréhension des Threads
    Bonjour à tous,

    Je n'arrive pas à comprendre un programme qui utilise des threads : c'est deux classes, une qui met des int dans un buffer, l'autre qui les prend.

    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
    // Producteur.java
    public class Producteur extends Thread {
        private Buffer buf;
        private int identité;
        public Producteur(Buffer c, int n) {
            buf = c; this.identité = n;
        }
    public void run() {
       for (int i = 0; i < 100; i++) {
           buf.mettre(i);
           System.out.println("Producteur #" + this.identité 
                            + " met : " + i);
           try { sleep((int)(Math.random() * 100));}
           catch (InterruptedException 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
    public class Consommateur extends Thread {
        private Buffer buf;
        private int identité;
         public Consommateur(Buffer c, int n) {
            buf = c;
            this.identité = n;
        }
        public void run() {
            int val = 0;
            for (int i = 0; i < 10; i++) {
                val = buf.prendre();
                System.out.println("Consommateur #" + 
                      this.identité + " prend: " + val);
            }
        }
    }
    Ce que j'ai du mal à comprendre c'est le but du sleep dans la classe Producteur.
    Pouvez-vous m'éclairer ?

    Merci d'avance.

  2. #2
    Membre averti
    Homme Profil pro
    Java
    Inscrit en
    Mai 2011
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2011
    Messages : 170
    Points : 444
    Points
    444
    Par défaut
    Sans tout le code c'est dur de vraiment savoir mais je peux te dire ceci :

    Le sleep sert à attendre un temps déterminer avant de remettre un autre élément (int ici) dans le buffer.

    Par contre juste une remarque, l'implémentation du producteur-consommateur ici est CATASTROPHIQUE.

    Je peux fournir plus de détails si besoin de savoir pourquoi mais c'est beaucoup plus technique.

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    D'accord, en gros on met un élément dans le buffer, on attend, et on en met un autre ? Mais c'est pas très utile, non ?

    Voilà la méthode main :
    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 class Main {
        public static void main(String[] args) {
            Buffer c = new Buffer();
            Producteur p1 = new Producteur(c, 1);
            Producteur p2 = new Producteur(c, 2); 
            Producteur p3 = new Producteur(c, 3);
     
            Consommateur c1 = new Consommateur(c, 1);
            Consommateur c2 = new Consommateur(c, 2);
            Consommateur c3 = new Consommateur(c, 3);
            p1.start();p2.start();p3.start();
            c1.start();c2.start();c3.start();
            }
        }
    C'est juste un exemple que j'ai dans mon cours, je ne l'ai pas implémenté moi-même (ce que j'aurais fait aurait été 3 fois plus moche ).

  4. #4
    Membre averti
    Homme Profil pro
    Java
    Inscrit en
    Mai 2011
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2011
    Messages : 170
    Points : 444
    Points
    444
    Par défaut
    J'aurais aimé avoir la classe Buffer avec ses méthodes.

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    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 class Buffer {
        private int valeur;
        private boolean available = false;
        public synchronized int prendre() {
            while (available == false) {
                try {wait();}
                catch (InterruptedException e) { }
            }
            available = false; notifyAll(); return valeur;
        }
        public synchronized void mettre(int val) {
            while (available == true) {
                try {wait();} catch (InterruptedException e) { }
            }
            valeur = val;available = true; notifyAll();
        }
    }
    Voilà pardon

  6. #6
    Membre averti
    Homme Profil pro
    Java
    Inscrit en
    Mai 2011
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2011
    Messages : 170
    Points : 444
    Points
    444
    Par défaut
    Ca va, la gestion est bonne mais maintenant je suis d'accord avec toi, le sleep ne sert pas à grand chose mis à part pour que tu puisses observer à l'oeil nu se qu'il se passe vraiment .

  7. #7
    Membre actif Avatar de fastdeath124
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Août 2011
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Août 2011
    Messages : 117
    Points : 200
    Points
    200
    Par défaut
    Je pense que ça sert uniquement à amplifier le blocage (le temps d'attente) afin de pouvoir observer le fonctionnement des producteurs et des consommateurs.
    Normalement, sans le "sleep" ça doit fonctionner correctement.

  8. #8
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Oui, dans certains cas même je me souviens en cours que le prof pour montrer les accès concurrent etc sous unix obligeait d'utiliser une pause manuelle (attente d'une touche) pour être certain de voir si on avait bien fait le travail. (bon dans ce cas il s'agissait d'accès concurrent à une DB mais le principe reste)
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Ok d'accord, donc ça n'a rien à voir avec le principe même de fonctionnement des threads. Parceque j'avais cru voir dans un autre cours sur le net qu'il devait y avoir un temps d'attente entre chaque tread, quelque chose du genre... Si je le retrouve je mettrai ici ^^'
    Merci pour les réponses.

  10. #10
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Ca ne serait pas plutôt "synchronisation" que temps d'attente que tu veux dire/as lu ?
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    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
    Citation Envoyé par wax78 Voir le message
    Ca ne serait pas plutôt "synchronisation" que temps d'attente que tu veux dire/as lu ?
    Un temps d'attente est une forme de synchronisation du pauvre. Sans temps d'attente, et avec plusieurs producteurs comme celui-ci qui accèdent au même Buffer, l'un des producteurs va être le premier à récupérer l'accès au buffer. Et il ne rendra pas cet excès aux autres, avant d'avoir terminé la totalité de sa tâche. En tout cas il y a peu de chance, car il ne se passe que quelques instructions entre chaque accès.
    Du coup, on aura d'abord un producteur qui fait tout son travail, puis un autre, puis un autre. Mais les producteurs ne mélangeront pas leur travail, et ne s'exécuteront donc pas vraiment en parallèle.

    Un temps d'attente l'oblige à relâcher les accès exclusifs qu'il possède et dont il n'est pas à l'intérieur pendant cette attente, résolvant ainsi ce problème. En plus, il libère aussi le processeur qui exécutait son thread, lui permettant d'aller en exécuter un autre.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Je suis un peu perdu pour le coup.

    C'est le sleep qui permet l'exécution en parallèle des Producteurs ici ? Ou c'est l'appel des méthodes de la classe Buffer (avec le wait() ) ?

  13. #13
    Membre averti
    Homme Profil pro
    Java
    Inscrit en
    Mai 2011
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2011
    Messages : 170
    Points : 444
    Points
    444
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Un temps d'attente est une forme de synchronisation du pauvre. Sans temps d'attente, et avec plusieurs producteurs comme celui-ci qui accèdent au même Buffer, l'un des producteurs va être le premier à récupérer l'accès au buffer. Et il ne rendra pas cet excès aux autres, avant d'avoir terminé la totalité de sa tâche. En tout cas il y a peu de chance, car il ne se passe que quelques instructions entre chaque accès.
    Du coup, on aura d'abord un producteur qui fait tout son travail, puis un autre, puis un autre. Mais les producteurs ne mélangeront pas leur travail, et ne s'exécuteront donc pas vraiment en parallèle.

    Un temps d'attente l'oblige à relâcher les accès exclusifs qu'il possède et dont il n'est pas à l'intérieur pendant cette attente, résolvant ainsi ce problème. En plus, il libère aussi le processeur qui exécutait son thread, lui permettant d'aller en exécuter un autre.

    Tout faux, le sleep ne permet que de laisser le temps à l'utilisateur de voir "ce qu'il se passe". En aucun cas le sleep gère l'accès concurrent.

    Le wait et le notifyAll des méthodes synchronized le font très bien

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Comment fonctionne la méthode wait() en gros ? Ca n'a pas de rapport avec le thread ?

  15. #15
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Si ca a un rapport.

    La méthode wait est la pour "bloquer ton thread" jusqu'a ce qu'un autre lui indique de poursuivre (avec un notify).

    Mais d'emblée je t'invite a lire ces tutoriels (surtout le premier qui parle de ca je pense).

    http://rom.developpez.com/java-synchronisation/
    http://alwin.developpez.com/tutorial/JavaThread/
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Ok je viens de capter le truc avec le booleen, le wait et le notify, merci.

    En fait je trouvais pas la méthode wait() dans la doc java sur les thread (http://docs.oracle.com/javase/1.4.2/...ng/Thread.html), je vais revoir le cours que tu as link sur la syncro (mais après une 10aine de min dessus je trouve ça quand même vachement compliqué ^^).

  17. #17
    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
    Citation Envoyé par Raikyn
    C'est le sleep qui permet l'exécution en parallèle des Producteurs ici ? Ou c'est l'appel des méthodes de la classe Buffer (avec le wait() ) ?
    Dans le cas présent, le wait() devrait suffire, puisqu'il force les threads à s'arrêter s'ils obtiennent l'accès exclusif deux fois de suite.

    Si le buffer acceptait plus d'un élément, wait() ne suffirait pas : cela dépend de la manière dont l'OS répartit les threads. sleep(), bien qu'assez sale, résoudrait au moins ce problème facilement.

    Citation Envoyé par kinaesthesia Voir le message
    Tout faux, le sleep ne permet que de laisser le temps à l'utilisateur de voir "ce qu'il se passe". En aucun cas le sleep gère l'accès concurrent.
    Pas volontairement, pas par nature. Mais en forçant le thread à s'arrêter, il le force à laisser la place aux autres threads après avoir eu l'accès exclusif.

    Citation Envoyé par kinaesthesia Voir le message
    Le wait et le notifyAll des méthodes synchronized le font très bien
    Elles garantissent l'accès exclusif et que si un thread est éligible pour prendre cet accès, alors un thread le prendra.
    Elles ne garantissent pas une répartition uniforme de cet accès entre les threads.
    Le buffer n'acceptant qu'un seul élément, wait() ne marche pas plus mal qu'un sleep() : un thread favorisé sera obligé de s'arrêter après avoir déposé ou pris un élément, et à la reprise il ne devrait pas être plus favorisé qu'un autre.

    Avec un buffer de plusieurs éléments, c'est une autre histoire. Cela dépend essentiellement de la gestion de synchronisation des threads de l'OS.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  18. #18
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Raikyn Voir le message

    En fait je trouvais pas la méthode wait() dans la doc java sur les thread (http://docs.oracle.com/javase/1.4.2/...ng/Thread.html),
    Parce que wait et notify sont des méhodes de la classe Object.

    Accessoirement, oui la programmation concurrent c'est compliqué, mais c'est comme ça. Quand on a N choses qui travaillent en parallèle, il faut se posser la question de savoir ce qu'on fait des données qu'elles traitent en même temps, donc il faut mettre en place des garde fous et des méthodes pour faire dialoguer tout ça. En plus, l'être humain et naturellement mono tâche dans sa reflexion, ce qui complique encore plus la compréhension des mécanismes impliqués


    Au delà de la programmation dans le cambouis des bases du multi thread comme tu fais, java fournis tout un tas de classes pour éviter de se casser la nenette

    Pour ton buffer par exemple, il existe le DeQueue en java qui gèrent le problème du producteur / consommateur. Tout se trouve dans java.util.concurrent.

  19. #19
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Ok merci à tous pour les infos

  20. #20
    Membre averti
    Homme Profil pro
    Java
    Inscrit en
    Mai 2011
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2011
    Messages : 170
    Points : 444
    Points
    444
    Par défaut
    Citation Envoyé par thelvin Voir le message

    Pas volontairement, pas par nature. Mais en forçant le thread à s'arrêter, il le force à laisser la place aux autres threads après avoir eu l'accès exclusif.
    Sur un Système temp réel (i.e : QNX) je t'aurais dis oui tu as raison, mais ici en Java sur un système non temps réel je dis que ca force le thread à s'arrêter oui mais pas forcément à donner l'accès aux autres.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Problème de compréhension des threads
    Par chimanos dans le forum Général Java
    Réponses: 12
    Dernier message: 25/10/2014, 08h59
  2. Variable globale / Propriété des threads
    Par rgarnier dans le forum XMLRAD
    Réponses: 4
    Dernier message: 03/10/2003, 10h49
  3. Problème de compréhension des ensembles
    Par Cornell dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 22h07
  4. [reseaux] Gestion des threads en perl
    Par totox17 dans le forum Programmation et administration système
    Réponses: 2
    Dernier message: 28/11/2002, 09h40
  5. Programmer des threads
    Par haypo dans le forum C
    Réponses: 6
    Dernier message: 02/07/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