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 :

Ordonnancement de Threads


Sujet :

avec Java

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Mars 2011
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Ordonnancement de Threads
    Bonjour tout le monde,

    Je me remets dans le Java après une longue pause et j'essaie de faire des p'tits trucs pour me remettre dans le bain mais je galère avec la gestion des Threads.

    Je vous expose mon problème : en fait, j'aimerais faire un programme avec 4 threads écrivant chacun une lettre (a pour le thread a, b pour le thread b etc). Le problème est que je voudrais que les lettres s'écrivent comme ceci : abcdabcdabcd... Or, pour le moment, mes lettres s'écrivent dans n'importe quel ordre ! En gros, je voudrais que le thread a écrive un 'a' puis une fois ceci fait, que le thread b écrive un 'b' etc

    J'ai looké pleins de cours sur la synchronisation des thread mais j'ai trouvé aucune réponse à mon problème.

    Je vous mets mon code pour le moment :

    Classe Letter
    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 Letter extends Thread {
     
        private Character letter;
         public Letter(Character letter) {
            this.letter = letter;
        }
        public void run() {
     	   for (int i = 0; i < 10; i++) {
                   System.out.print(this.letter);
        	       try { sleep((int)(Math.random() * 100));}
        	       catch (InterruptedException e) { }
     	   }
        }
    }

    Classe 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
    15
    16
    17
    18
    public class Main {
     
        public static void main(String[] args) {
            Letter a = new Letter('a');
            Letter b = new Letter('b');
            Letter c = new Letter('c');
            Letter d = new Letter('d');
     
     
            a.start();
            b.start();
            c.start();
            d.start();
     
     
            }
     
    }

    Je vous remercie d'avance pour votre aide.

    Nico

  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,


    Question : pourquoi utiliser des threads ?
    Puisque tu as besoin d'un ordre précis il ne s'agit pas d'un traitement en parallèle mais d'un traitement séquentielle (il n'y a qu'une seule tâche à la fois).

    Dans ce cas précis tu devras mettre en place une synchronisation lourde pour rien !!!




    Si c'est un exemple pour un besoin bien précis, il serait préférable de présenter ce besoin pour donner une solution adapté...

    a++

  3. #3
    En attente de confirmation mail
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Octobre 2010
    Messages
    501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2010
    Messages : 501
    Points : 1 060
    Points
    1 060
    Par défaut
    Bonjour,

    Les thread doivent partager une ressource pour savoir à qui c'est le tour d'écrire.

    Une propriété static dans la classe Letter devrait permettre de faire ça.
    Chaque thread lorsque c'est son tour écrit puis passe la main au suivant en modifiant la propriété.

  4. #4
    Nouveau Candidat au Club
    Inscrit en
    Mars 2011
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    C'est en fait un exercice d'entraînement de mon cours de Programmation Concurrente et Distribuée. Il nous est demandé, je cite, de faire 3 programmes avec 4 processus qui écrivent les lettres a,b,c,d de l'alphabet :
    - d'abord sans ordre précis
    - puis dans l'ordre abcdabcdabcd...
    - puis en intercalant les lettres a et d entre les lettes b et c

    Il est vrai qu'il est question ici de processus simples car il s'agit seulement d'une écriture mais ceci est pour ensuite voir plus loin : notamment, avoir 4 processus réalisant 4 tâches bien précises (dans une usine par exemple) et ces 4 tâches devant toujours être réalisées dans le même ordre... C'est pourquoi je pense que cet exercice est intéressant.

    Merci pour ta réponse en tout cas

  5. #5
    Nouveau Candidat au Club
    Inscrit en
    Mars 2011
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Nudger Voir le message
    Bonjour,

    Les thread doivent partager une ressource pour savoir à qui c'est le tour d'écrire.

    Une propriété static dans la classe Letter devrait permettre de faire ça.
    Chaque thread lorsque c'est son tour écrit puis passe la main au suivant en modifiant la propriété.
    J'y ai pensé, mais comment faire en sorte que le thread 'b' sache que c'est son tour après le thread 'a', et non pas le 'c' ni le 'd' ?

  6. #6
    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
    on va accepter le fait que ce soit un exercice donc (même si ça en est un très mauvais à mon avis).

    Chaque Thread va avoir l'ordre d'exécution suivant:

    attendre la ressource dont il a besoin
    effectuer son travail
    informé qu'il a créé une ressource (pour l'autre qui en a besoin)


    C'est chiant et complexe à faire. Heureusement, java récent est gentils et te fournis un truc bien utile: les BlockingQueue (qui correspondent, d'ailleurs, à ta simulation), donc l'implémentation ArrayBlockingQueue.

    Reprenons:

    Thread A est une "chaine de production qui produit des A quand des D sont disponibles", Thread B est une" chaine de production qui produit des B quand des A sont disponible", etc

    Tu as donc
    4 chaines de productions (les threads)
    et quatres bacs à produits que tu dois surveiller et remplir (les Queue). Ces derniers peuvent être implémentés par une ArrayBLockinQueue. Ces Queues sont remplis par un Thread et lues par un autre. Elle ont une taille max (dans ton cas 1). Tu devra donc avoir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ThreadX:
    while(true){
       lire dans queue d'entrée
       afficher mon texte
       écrire dans queue de sortie
    }
    Voilà, t'aura juste à poser un truc dans la queue d'entrée de Thread A au début pour lancer tout le bazar Aucun wait, aucun notify, la Queue fait le boulot pour toi

  7. #7
    Nouveau Candidat au Club
    Inscrit en
    Mars 2011
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    on va accepter le fait que ce soit un exercice donc (même si ça en est un très mauvais à mon avis).

    Chaque Thread va avoir l'ordre d'exécution suivant:

    attendre la ressource dont il a besoin
    effectuer son travail
    informé qu'il a créé une ressource (pour l'autre qui en a besoin)


    C'est chiant et complexe à faire. Heureusement, java récent est gentils et te fournis un truc bien utile: les BlockingQueue (qui correspondent, d'ailleurs, à ta simulation), donc l'implémentation ArrayBlockingQueue.

    Reprenons:

    Thread A est une "chaine de production qui produit des A quand des D sont disponibles", Thread B est une" chaine de production qui produit des B quand des A sont disponible", etc

    Tu as donc
    4 chaines de productions (les threads)
    et quatres bacs à produits que tu dois surveiller et remplir (les Queue). Ces derniers peuvent être implémentés par une ArrayBLockinQueue. Ces Queues sont remplis par un Thread et lues par un autre. Elle ont une taille max (dans ton cas 1). Tu devra donc avoir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ThreadX:
    while(true){
       lire dans queue d'entrée
       afficher mon texte
       écrire dans queue de sortie
    }
    Voilà, t'aura juste à poser un truc dans la queue d'entrée de Thread A au début pour lancer tout le bazar Aucun wait, aucun notify, la Queue fait le boulot pour toi

    Merci, je vais me renseigner sur cela, même si je ne pense pas que cet exercice a vocation à utiliser cet ArrayBlockingQueue car c'est "censé" être un exercice "de base" sur les Threads. C'est d'ailleurs super frustrant de ne pas réussir un exercice décrit comme "la base" pour comprendre la notion de Threads et de synchronisation

  8. #8
    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
    synchroniser un thread avec deux autres, le tout en circulaire et ne pas avoir de deadlock, c'est pas vraiment ce que je qualifie de "basique" personellement

    Le nombre de sémaphores et de verrous nécessaire risque d'etre assez impressionant. C'est pas le tout de faire un wait, faut s'assurer que les autres threads ne feront pas le notify avant qu'on fasse le wait.

  9. #9
    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
    Citation Envoyé par nspsg Voir le message
    C'est d'ailleurs super frustrant de ne pas réussir un exercice décrit comme "la base" pour comprendre la notion de Threads et de synchronisation
    Désolé mais ce n'est pas vraiment un exercice de base

    C'est juste une synchronisation un peu stupide car cela simule de l'itératif...
    La notion de Producteur/Consommateur se rapprocherait plus d'un exercice de base !



    Dans ton cas tu peux faire ceci :
    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
    public class Letter extends Thread {
     
    	/** Le lock qui permettra de synchronized les threads */
    	private static final Object LOCK = new Object();
     
    	/** Le modulo représentant le nombre de thread */
    	private static final int MODULO_ORDER = 4;
    	/** Le numéro d'ordre du thread qui peu s'exécuter */
    	private static int current = 0;
     
     
    	private final int order;
    	private final char letter;
     
    	public Letter(char letter, int order) {
    		this.order = order;
    		this.letter = letter;
    	}
     
    	private void printLetter() throws InterruptedException {
    		// On synchronize sur un objet commun à tous les thread :
    		synchronized (LOCK) {
    			// Tant que ce n'est pas notre tour :
    			while (this.order != current) {
    				LOCK.wait(); // on se met en pause et on libère le lock
    			}
     
    			// On peut enfin écrire la lettre :
    			System.out.print(this.letter);
     
    			// On modifie la lettre à accepter (on passe à la suivante)
    			current = (current+1) % MODULO_ORDER;
     
    			// Et on réveille tous les autres threads...
    			LOCK.notifyAll();
    		}
    	}
     
    	public void run() {
    		for (int i = 0; i < 10; i++) {
    			try {
    				printLetter();
    				Thread.sleep((int) (Math.random() * 100));
    			} catch (InterruptedException e) {
    				throw new RuntimeException(e);
    			}
    		}
    	}
     
    	public static void main(String[] args) throws IOException {
    		Letter a = new Letter('a', 0);
    		Letter b = new Letter('b', 1);
    		Letter c = new Letter('c', 2);
    		Letter d = new Letter('d', 3);
     
    		a.start();
    		b.start();
    		c.start();
    		d.start();
    	}
    }
    Mais bon c'est tout pourri quand même

    a++

  10. #10
    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
    'ffectivement, c'est moche, une seul lock pour tous, tout le monde qui se réveille. Mais c'est le plus simple à écrire sans utiliser les apis bien pratiques de java je pense

  11. #11
    Nouveau Candidat au Club
    Inscrit en
    Mars 2011
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Je vous remercie beaucoup pour votre aide, je vais quand même de suite envoyer un mail à l'intervenant de ce cours pour savoir quel est, selon lui, l'intérêt de cet exercice et qu'est ce qu'il attendait de nous pour le résoudre...
    Je vous tiens au courant de sa réponse, au plus vite

Discussions similaires

  1. Sémaphores et ordonnancement des threads
    Par Nymar dans le forum Débuter
    Réponses: 0
    Dernier message: 11/04/2013, 20h05
  2. Ordonnancement Thread Java
    Par mi_info dans le forum Général Java
    Réponses: 11
    Dernier message: 05/01/2011, 15h08
  3. Ordonnancement des thread
    Par ayoub2007 dans le forum Général Java
    Réponses: 2
    Dernier message: 17/05/2010, 19h54
  4. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  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