[Java] Threads(simple mais je capte pas )

Threads(simple mais je capte pas ) [Java] - Java - Programmation

Marsh Posté le 15-10-2003 à 19:57:02    


Code :
  1. class File{
  2.    private static LinkedList li=new LinkedList();
  3.    private static Random r=new Random();
  4.    public synchronized void Vote() {
  5.    if (empty()){
  6.           try{
  7.           System.out.println("wait" );
  8.              wait(); // mise en attente
  9.           }
  10.           catch(Exception e){}
  11.        }
  12.          System.out.println(li.removeLast());
  13.    }
  14.    public synchronized void Add(int i) {//
  15.           li.addFirst("Voteur "+(i+1));
  16.           notify();
  17.           try{
  18.              Thread.sleep(r.nextInt(100));
  19.           } catch(InterruptedException IE){};
  20.    }
  21.    public boolean empty() {return (li.size()==0);}
  22. }


 
jai 2 threads :
une qui executre 100 fois Add(int) et l'autre 100 fois Vote()
les deux threads activent une methode sur un objet de type File
c le meme objet, passé par argument lors de lappel au constructeur des threads
 
le probleme est que le premier thread reste bloque sur le wait tandis que lautre avance toute le temps et fait ces 100. c seulement a ce moment que lautre thread demarre et fait les votes

Reply

Marsh Posté le 15-10-2003 à 19:57:02   

Reply

Marsh Posté le 15-10-2003 à 20:35:09    

red faction a écrit :


le probleme est que le premier thread reste bloque sur le wait tandis que lautre avance toute le temps et fait ces 100. c seulement a ce moment que lautre thread demarre et fait les votes

T'es sur qu'il est bloqué le premier ?
 
C'est pas plutôt qu'il est débloqué mais que le processeur n'a aucun intérêt à lui donner la main tant que l'autre n'est pas fini pour diminuer le nombre de changement de contexte ?
 
(je ne vérifie pas tes synchronised car j'en ai marre de lire la doc pour les autres, mais à l'intuite j'aurais dit que c'est toute la classe qui devrait être "synchronised" ).

Reply

Marsh Posté le 15-10-2003 à 20:43:33    

nraynaud a écrit :

T'es sur qu'il est bloqué le premier ?
 
C'est pas plutôt qu'il est débloqué mais que le processeur n'a aucun intérêt à lui donner la main tant que l'autre n'est pas fini pour diminuer le nombre de changement de contexte ?
 
(je ne vérifie pas tes synchronised car j'en ai marre de lire la doc pour les autres, mais à l'intuite j'aurais dit que c'est toute la classe qui devrait être "synchronised" ).


 
jai fait un system.out.println apres le wait et il na pas marche pas. dans le 1er thread (celui avec les add javais mit un Thread.sleep(10000); et ca marche qd meme pas  :(

Reply

Marsh Posté le 15-10-2003 à 20:49:48    

ah oui, non, je viens de capter (tu fais un sémaphore privé) tu fais ton sleep dans la méthode synchronised, donc avec le lock.

Reply

Marsh Posté le 15-10-2003 à 21:34:30    

lobjet file est créé dans mon main puis passé comme argument a mes thread ca pose un prob ????

Reply

Marsh Posté le 15-10-2003 à 21:45:36    

non, le problème c'est que tu fais le sleep dans la méthode add() alors qu'il faut le faire à l'extérieur.

Reply

Marsh Posté le 15-10-2003 à 21:50:59    

nraynaud a écrit :

non, le problème c'est que tu fais le sleep dans la méthode add() alors qu'il faut le faire à l'extérieur.


 
je viens juste de le trouver merci bien qd meme  :jap:

Reply

Marsh Posté le 15-10-2003 à 22:31:06    

nraynaud a écrit :

non, le problème c'est que tu fais le sleep dans la méthode add() alors qu'il faut le faire à l'extérieur.


ok, mais après le sleep, la méthode add se termine => le lock est libéré => l'autre thread devrait prendre la main puisqu'il est en attente ...
je trouve quand même bizarre que l'autre Thread ne reprenne jamais la main ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 15-10-2003 à 22:49:51    

benou a écrit :


ok, mais après le sleep, la méthode add se termine => le lock est libéré => l'autre thread devrait prendre la main puisqu'il est en attente ...
je trouve quand même bizarre que l'autre Thread ne reprenne jamais la main ...

bah non, il a le proc, il a du boulot, il a rien qui l'empêche d'avancer, il a pas consomé beaucoup de temps (le sleep ne compte pas, car il s'est fait dégager pendant ce temps là), un switch ça coûte cher. Alors que l'autre dort, n'est réveillable que depuis peu et n'est nécessaire à personne pour que ça avance.
 
edit : je pense pas qu'une sortie de méthode soit un point de décision pour l'ordonnanceur, par contre, une petite entrée-sortie ça peut faire basculer.


Message édité par nraynaud le 15-10-2003 à 22:51:28
Reply

Marsh Posté le 16-10-2003 à 00:04:49    

c'est pas que depuis peu, c'est systématiquement 100 fois de suite !


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 16-10-2003 à 00:04:49   

Reply

Marsh Posté le 16-10-2003 à 00:20:00    

Code :
  1. class File{
  2.    private static LinkedList li=new LinkedList();
  3.    private static int totalvote;
  4.    public synchronized String Vote() {//
  5.      while (empty()){
  6.           try{
  7.              System.out.println("wait "+totalvote);
  8.              wait(); // mise en attente
  9.              if(!Continue()){
  10.                return null;
  11.              }
  12.           }
  13.           catch(InterruptedException e){}
  14.      }
  15.      System.out.println("vote "+totalvote);
  16.      totalvote++;
  17.      notifyAll();
  18.      return ((String)li.removeLast());
  19.    }
  20.    synchronized boolean Continue(){
  21.       if(totalvote>=100) notifyAll();
  22.       return(totalvote<100);
  23.    }
  24.    public synchronized void Add(int i) {//
  25.        while (full()) {
  26.           try {
  27.                wait();  // mise en attente
  28.           }
  29.           catch(Exception e) {}
  30.        }
  31.        li.addFirst("Voteur "+(i+1));
  32.        notifyAll();
  33.        System.out.println(" add to list" );
  34.    }
  35.    public boolean full() {return (li.size()==10);} //file de 3 personnes max
  36.    public boolean empty() {return (li.size()==0);}
  37. }


 
voila la version finale, marche nikel

Reply

Marsh Posté le 16-10-2003 à 00:35:49    

bon euh drapeau.


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 16-10-2003 à 01:03:31    

benou a écrit :

c'est pas que depuis peu, c'est systématiquement 100 fois de suite !  

Bah oui, mais à chaque fois que notre ami voteur aurait la possibilité d'être débloqué parceque monsieur ajouteur est en rade sur son timer, seigneur voteur peut pas se débloquer parce qu'il peut pas bouger le petit doigt de la section critique parceque l'ajouteur boulet la squatte.
 
100 fois de suite, à l'ocasion de prendre le processeur grâce à la notification et à l'arrêt de l'ajouteur, le voteur est bloqué parce que l'ajouteur dort dans la section critique.

Reply

Marsh Posté le 16-10-2003 à 01:26:26    

ce que je comprend pas c'est que le voteur prenne pas la main au moment où l'ajouteur sort da la fonction (après le sleep). Là il a tout le loisir de prendre le lock le temps que l'ajouteur retourne dans la méthode d'ajout.


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 16-10-2003 à 01:53:28    

benou a écrit :

ce que je comprend pas c'est que le voteur prenne pas la main au moment où l'ajouteur sort da la fonction (après le sleep). Là il a tout le loisir de prendre le lock le temps que l'ajouteur retourne dans la méthode d'ajout.


Parce qu'il ne reste pas assez de temps en dehors, et qu'il ne fait aucune action suceptible de déclencher un ré-ordonnancement en dehors. D'autant plus que ça fait très peu de temps qu'il a la main (sortie du sleep) quand il sort, il a donc un beau crédit-temps tout neuf à écluser alors que l'autre n'était pas prête à la dernière vérification.

Reply

Marsh Posté le 17-10-2003 à 10:15:28    

Si je comprends bien, c'est beaucoup plus intelligent de faire des :

Code :
  1. synchronized(this) {
  2.   this.wait();
  3. }

et des

Code :
  1. synchronized(this) {
  2.   this.notify();
  3. }


que de déclarer les méthodes synchronisées, pour ce qui est synchronisation de threads.
 
Pour l'accès à des ressources critiques, c'est différent, évidemment, mais ça doit pouvoir se régler indépendamment par un :

Code :
  1. List li = Collections.synchronizedList(new LinkedList());


Message édité par BifaceMcLeOD le 17-10-2003 à 10:16:09
Reply

Marsh Posté le 17-10-2003 à 12:32:23    

BifaceMcLeOD a écrit :

Si je comprends bien, c'est beaucoup plus intelligent de faire des :

Code :
  1. synchronized(this) {
  2.   this.wait();
  3. }

et des

Code :
  1. synchronized(this) {
  2.   this.notify();
  3. }


que de déclarer les méthodes synchronisées, pour ce qui est synchronisation de threads.


On peut aussi mieux faire : synchroniser sur un objet créé spécialement pour ça. Cela évite ainsi d'interférer avec d'autres objets qui auraient la mauvaise idée d'utiliser ton objet pour synchronizer autre chose.


---------------
"Colère et intolérance sont les ennemis d'une bonne compréhension." Gandhi
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed