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

Langage Java Discussion :

probleme de synchronization


Sujet :

Langage Java

  1. #1
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Points : 6
    Points
    6
    Par défaut probleme de synchronization
    Bonjour,
    bon voilà mon probleme, je tente de synchroniser deux treads, alors j'ai une class Inf qui affiche un text divisé en deux morceaux, séparé par un laps de temps,donc dans ce sens :

    affichage partie 1 du texte
    attente de 2 sec
    affichage partie 2 du txt

    donc c'est tres simple,tout se complique ici, je lance ce petit code avec deux threads distinct, donc thread a et thread b , le probleme est que quand je lance le thread a, je veux que le thread b attende que le thread a soit fini.


    A priori, avec synchronized; le thread b ne peut pas acceder au thread princiapal tant que celui ci n'est pas fini, mais ça ne marche pas :

    voici mon code :

    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
    public class Inf implements Runnable{
     
    	protected String text;
    	protected String number;
     
    	public Inf(String text){
    		this.text  = text;
    	}
     
    	public void run(){
    		while(true){
    			try{
    					Thread.sleep(10);
    			}catch(InterruptedException e){ System.out.println(e);	}
    			displayAll();	
    		}
    	}
     
     
    	public synchronized void displayAll(){
    		displayPartOne();
    		try{
    			Thread.sleep(2000);
    		}catch(InterruptedException e){ System.out.println(e);	}
    		displayPartTwo();
    	}
     
    	public synchronized void displayPartOne(){
    		System.out.print(textPartOne());
    	}
     
    	public synchronized void displayPartTwo(){
    		System.out.println(textPartTwo());
    	}
    	public String textPartOne(){
    		String res="";
    		for(int i=0;i < text.length()/2;i++){
    			res += text.charAt(i);
    		}
    		return res;
    	}
     
    	public String textPartTwo(){
    		String res="";
    		for(int i=text.length()/2;i < text.length();i++){
    			res += text.charAt(i);
    		}
    		return res;
    	}
    	// to help me for debuging	
    	public void setNumber(String number){	this.number = number; }
     
    	public String toString(){
    		return "thread n  : "+number;
    	}	
    }
    et la classe Client :

    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 Client{
     
    	public Client() throws Exception{
    		Inf a = new Inf("Victor is a man");
    		a.setNumber("1");
    		Inf b = new Inf("Cleopa is a cat");
    		b.setNumber("2");
     
    		Thread ta = new Thread(a);
    		Thread tb = new Thread(b);
    		ta.start();
    		tb.start();
    	}
     
    	public static void main(String [] args)  throws Exception{
    		new Client();	
    	}
    }
    laffichage est le suivant :

    Victor Cleopa is a man
    is a cat
    Victor Cleopa is a man
    is a cat
    Victor Cleopa
    on voit que victor devient un chat et cleop devient un homme..

    le probleme est clair ici, a la premiere ligne, Victor et Cleopa accede a la methode display tous les deux, alors que je pensais que Cleopa ne pouvait pas s'afficher tant que Victor n'avait pas fini..

    quelqu'un peut m'aider

  2. #2
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Ta synchronisation ne sert à rien ici, vu que le thread ta exécute les méthodes synchronisées sur l'objet a, et que le thread tb exécute les méthodes synchronisées sur l'objet b. Elles ne sont pas synchro "entre-elles".

    De plus, même si tu les synchronisais entre-elles, tu n'as aucune garantie que ta soit exécuté avant b.
    Dans ton cas (déjà pourquoi avoir 2 threads et non 1 seul?), tu lances ta (ta.start()), puis tu fais ta.join() avant de lancer tb (tb.start()). Comme ça tu attends que ta soit fini avant de lancer tb...

  3. #3
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    techniquement ca devrait marcher hormis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ~/progs/Java/project2 $ java Client
    Exception in thread "main" java.lang.IllegalMonitorStateException
            at java.lang.Object.wait(Native Method)
            at java.lang.Object.wait(Object.java:474)
            at Client.<init>(Client.java:12)
            at Client.main(Client.java:17)

  4. #4
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Tu peux nous montrer le code correspondant?

  5. #5
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    je ne l'ai plus, je l'ai changé, mais j'ai toujours la meme erreur, je me suis dit qu'avec un compteur synchronizé, j'arriverai a definir si je dois mettre en pause le thread ou non, mais j'ai exactement la meme exception qui se lance :/

    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
    import java.util.concurrent.*;
     
    public class Inf implements Runnable{
     
    	protected  String text;
    	protected String number;
    	protected static int count=0;
     
    	public Inf(String text){
    		this.text  = text;
    	}
     
    	public void run(){
    		while(true){
    			synchronized(this){
    				if(getCount() != 0){
    					try{
    						System.out.print("text is : "+text);
    						System.out.println("     count : "+getCount());
    						Thread.currentThread().wait();
    					}catch(InterruptedException e){ System.out.println(e);	}
    				}
    				else{
    					count++;
    					displayPartOne();
    					try{
    						Thread.sleep(2000);
    					}catch(InterruptedException e){ System.out.println(e);	}
    					displayPartTwo();
    					count--;
    					notify();
    				}
    			}
    		}
    	}
     
     
    	public synchronized int getCount(){	return count;	}
    	public  void displayPartOne(){
    		System.out.print(textPartOne());
    	}
     
    	public void displayPartTwo(){
    		System.out.println(textPartTwo());
    	}
    	public String textPartOne(){
    		String res="";
    		for(int i=0;i < text.length()/2;i++){
    			res += text.charAt(i);
    		}
    		return res;
    	}
     
    	public String textPartTwo(){
    		String res="";
    		for(int i=text.length()/2;i < text.length();i++){
    			res += text.charAt(i);
    		}
    		return res;
    	}
    	// to help me for debuging	
    	public void setNumber(String number){	this.number = number; }
     
    	public String toString(){
    		return "thread n  : "+number;
    	}	
    }

  6. #6
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Pourquoi tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread.currentThread().wait();
    Ca n'a pas de sens...

    Fait:

  7. #7
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    javais essayé les deux , le resultat de wait(), est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     java Client
    Victor text is : Cleopa is a cat     count : 1
    is a man
    Victor is a man
    le wait a l'air de fonctionner, le probleme est que le premier thread ne rend jamais la main.. je ne sais pas s'il s'agit d'un probleme de notify ou d'implementation

  8. #8
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    oui donc j'ai vérifié, le wait ne se debloque jamais :/ sinon je pense que mon system macherait, as tu une idée du pourquoi?

    peut etre parce que le notify libere l'objet, et etant donné qu'il ne s'agit pas du meme oject, ça ne peut donc pas liébérer le deuxieme thread(hypothese)

    ps : a noter que notifyAll() ne marche pas non plus, meme probleme que précédemment

  9. #9
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    C'est sans doute simplement parce que dans ton test, getCount() == 0 n'est jamais possible, donc pas de notify...

  10. #10
    Futur Membre du Club
    Inscrit en
    Octobre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    alors si tu regardes bien le code, le notify ne passe pas dans l'instruction if(getCount==0), donc il n y a pas de rapport.

    ensuite, si tu regarde l'execution ,un thread affiche l'etat de passage dans le if ,et se bloque au wait(), et un autre thread, ne passe pas dans le if, affiche ce qu'il doit afficher ("victor is a man"),en ensuite fini par executé le notify(), le probleme , c'est que ce notify() ne libere pas le wait() cité plus haut..

  11. #11
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par nevroo
    alors si tu regardes bien le code, le notify ne passe pas dans l'instruction if(getCount==0), donc il n y a pas de rapport.
    Et si tu regardes bien, le bloc contenant le notify() est dans un "else", et donc si le else n'est jamais exécuté, le notify() non plus...

    Ensuite, le count n'est jamais modifié. Enfin, il y a un count++ et un count--, mais ils ne servent à rien (c'est le thread qui a le verrou, et donc cette opération est vue comme atomique par l'autre thread, et count++ suivi de count-- en atomique, ça ne fait pas grand chose)...

Discussions similaires

  1. probleme Modélisation de la machine synchrone
    Par slimebdx dans le forum Simulink
    Réponses: 0
    Dernier message: 01/02/2011, 14h35
  2. Réponses: 0
    Dernier message: 18/12/2008, 16h18
  3. probleme avec synchronized,wait
    Par lexu1213 dans le forum Langage
    Réponses: 3
    Dernier message: 23/07/2007, 09h34
  4. Probleme synchronize et semaphore
    Par rvzip64 dans le forum Langage
    Réponses: 1
    Dernier message: 03/05/2006, 19h20
  5. [Thread][SYNCHRONIZED] problème de synchornisation
    Par _Eric_ dans le forum Général Java
    Réponses: 9
    Dernier message: 15/03/2005, 10h59

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