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 avec synchronized,wait


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2007
    Messages : 21
    Points : 13
    Points
    13
    Par défaut probleme avec synchronized,wait
    Bonjour,

    Alors pour commencer je vous donne 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
     
    public static void main(String[] args) {
     
          final Object wham= new Object();
    		Runnable singer= new Runnable() {
    			public void run() {
    				try {
    					for (int i= 1; i<=100; i++){
    						synchronized (wham) { 
    					         System.out.println("debut :" +i);
    						 wham.wait(); 
    						 System.out.println("fin : "+i);
    						}
    					}
    				} catch (InterruptedException e) {
    						System.err.println("error"+e);
    			        }
    		        }        
                   };
     
    	Thread george= new Thread(singer, "George");
    	Thread andrew= new Thread(singer, "Andrew");
    	george.start(); andrew.start();
     
             int i= 0;
    		while ( george.isAlive() || andrew.isAlive()) {
    			synchronized (wham)  {
                            wham.notify();
                            System.out.println("Notify : "+i);}
    		         i++;
    			}
    		System.out.println("\nI had to send " + i + " notifications.");
    		}

    Maintenant je vous donne le resultat de la console(sequence de fin) :

    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    debut : 98
    debut : 98
    Notify : 2804
    Notify : 2805
    Notify : 2806
    Notify : 2807
    Notify : 2808
    Notify : 2809
    Notify : 2810
    Notify : 2811
    Notify : 2812
    Notify : 2813
    Notify : 2814
    Notify : 2815
    Notify : 2816
    Notify : 2817
    Notify : 2818
    Notify : 2819
    Notify : 2820
    Notify : 2821
    Notify : 2822
    Notify : 2823
    Notify : 2824
    Notify : 2825
    Notify : 2826
    Notify : 2827
    Notify : 2828
    Notify : 2829
    Notify : 2830
    Notify : 2831
    Notify : 2832
    Notify : 2833
    Notify : 2834
    fin : 98
    fin : 98
    Notify : 2835
    debut : 99
    debut : 99
    Notify : 2836
    Notify : 2837
    Notify : 2838
    Notify : 2839
    Notify : 2840
    Notify : 2841
    Notify : 2842
    Notify : 2843
    Notify : 2844
    Notify : 2845
    Notify : 2846
    Notify : 2847
    Notify : 2848
    Notify : 2849
    Notify : 2850
    Notify : 2851
    Notify : 2852
    Notify : 2853
    Notify : 2854
    Notify : 2855
    Notify : 2856
    Notify : 2857
    Notify : 2858
    Notify : 2859
    Notify : 2860
    Notify : 2861
    Notify : 2862
    Notify : 2863
    Notify : 2864
    Notify : 2865
    Notify : 2866
    fin : 99
    fin : 99
    Notify : 2867
    debut : 100
    debut : 100
    Notify : 2868
    Notify : 2869
    Notify : 2870
    Notify : 2871
    Notify : 2872
    Notify : 2873
    Notify : 2874
    Notify : 2875
    Notify : 2876
    Notify : 2877
    Notify : 2878
    Notify : 2879
    Notify : 2880
    Notify : 2881
    Notify : 2882
    Notify : 2883
    Notify : 2884
    Notify : 2885
    Notify : 2886
    Notify : 2887
    Notify : 2888
    Notify : 2889
    Notify : 2890
    Notify : 2891
    Notify : 2892
    Notify : 2893
    Notify : 2894
    Notify : 2895
    Notify : 2896
    Notify : 2897
    fin : 100
    fin : 100
    Notify : 2898
     
    I had to send 2899 notifications.

    Voila,alors mon probleme c est que je ne comprends pas pourquoi il faut 2899 notify (parfois + ou moins ce n est jamais fixe) afin de debloquer 200 wait(2 thread avec 100 wait chacun) ...Je pensais que lorsqu on faisait wait a un thread il suffisait d 1 seul notify afin de le debloquer.....
    Je pense que je n ai pas trop bien compris le synchronised....

    Si quelqu un arrive a m eclairer sur ca serait super sympa!!!
    merci!!!

  2. #2
    Membre expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Points : 3 675
    Points
    3 675
    Par défaut
    Hello,

    il faut lire la doc de notify...

    Citation Envoyé par Javadoc de notify
    Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
    The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
    Notify réveille un thread au hasard parmis ceux qui sont en attente...

    Et de toute façon, on ne peut pas prédire à quel moment un thread va réellement se réveiller ou s'arrêter, et tout pendant que le bloc synchronized n'est pas terminé, c'est le même thread qui reste en activité.

    perso je rajouterais un simple "try {Thread.sleep(100);} catch(InterruptedException e){/* Ignorée */}" juste après que tu fermes le bloc synchronized qui contient le notify afin de forcer ce thread-là à se mettre en sommeil pour une durée minimale... ce qui va donner de grandes chances de se réveiller au thread que tu as notifié

    ça devrait déjà limiter le nombre d'appels à notify


  3. #3
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Et c'est surtout parce que la commutation ne se déclenche pas immédiatement au notify ; le réveil du thread en attente sur l'objet notifié aura lieu simplement à la prochaine commutation normale. Par conséquent ta boucle while continue, même après le notify, et peut donc déclencher une grosse quantité d'entre eux, alors que le thread à réveiller attend simplement la prochaine commutation pour l'être vraiment.

    Heu... est-ce que ce que je dis est clair ?...

    (d'autant que cela revient à peu près à ce qu'à dit Pill_S ! )

  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
    Si tu veux avoir un mécanisme qui "mémorise" les notify(), il faut utiliser des sémaphores...

    C'est un système de jetons, quand tu libères des jetons, la valeur du sémaphore s'incrémente, quand tu en prends, il diminue (et c'est bloquant s'il n'y a pas de jetons)...

Discussions similaires

  1. probleme avec wait
    Par zorba49 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 25/08/2005, 10h38
  2. Probleme avec la copie des surfaces
    Par Black_Daimond dans le forum DirectX
    Réponses: 3
    Dernier message: 09/01/2003, 10h33
  3. probleme avec la touche F10
    Par b.grellee dans le forum Langage
    Réponses: 2
    Dernier message: 15/09/2002, 22h04
  4. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17
  5. [Kylix] probleme avec un imagelist
    Par NicoLinux dans le forum EDI
    Réponses: 4
    Dernier message: 08/06/2002, 23h06

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