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

Java Discussion :

Synchronisation - concurrence


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 26
    Par défaut Synchronisation - concurrence
    Bonjour,


    j'ai une question à propos de la synchronisation des Thread :

    Ma classe A possède un compteur et 2 méthodes.

    Une méthode augmente la valeur du compteur de 1 et une autre, si la valeur du compteur est égal à 10, diminue la valeur du compteur de 1.

    Je sais que dans un environnement multi-utilisateurs, les opérations d'incrémentation et de décrémentation du compteur doivent être dans un bloc synchronized.

    Mais, est-ce que le test de la valeur du compteur avant son éventuelle décrémentation doit être compris dans le bloc synchronized ou bien seulement l'opération de décrémentation ?

    Merci beaucoup !

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 974
    Par défaut
    Citation Envoyé par Pacma Voir le message
    .

    Je sais que dans un environnement multi-utilisateurs, les opérations d'incrémentation et de décrémentation du compteur doivent être dans un bloc synchronized.

    !
    pourquoi n'utilises-tu pas un AtomicInteger ?

  3. #3
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    C'est ton programme, c'est toi qui sait le comportement attendu dans ce type de cas.
    En tout cas, ne pas synchroniser le test veut dire que tu peux depasser la valeur 10 (si l'incrémentation à lieu entre la vérification de la valeur). A voir si c'est ce que le compteur est sensé faire ou pas.

    Dans la plupart des cas, il faut synchroniser la totalité des blocs. Lorsque les utilisateurs utilisent des objets threadsafe (ex: Vector), ils ont tendance à oublier qu'il faut quand meme synchroniser les acces (typicalement add/remove) mais aussi l'acces complet au vector. Ca souvent, on utilise ceux-ci dans des foreach. Et si un add/remove arrive pendant ce temps, c'est le drame...

    C'est un peu le genre de problématique que tu as. Donc sans trop savoir comment fonctionne ce compteur, j'aurais tendance à penser qu'il faut synchroniser l'ensemble.

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 26
    Par défaut
    plawyx : tout simplement parce que je ne connaissais pas les AtomicInteger.

    hwoarang : donc par sécurité il faut mieux synchroniser le bloc.


    Merci !

  5. #5
    Membre Expert Avatar de Nico02
    Homme Profil pro
    Developpeur Java/JEE
    Inscrit en
    Février 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Février 2011
    Messages : 728
    Par défaut
    Salut,

    Il faut le mettre à l'intérieur du block de synchronisation.

    Le plus important dans ce genre de cas est de sécuriser l'accès à la donnée critique, donc la lecture et l'écriture.

    Le plus simple est de déclarer ta méthode synchronized, comme ça tu es sûr de la cohérence de ta donnée.

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Réponse courte : oui. Sans synchronisation les threads ne peuvent pas voir les modifications faites par les autres threads.
    Donc une synchronisation est obligatoire quand on veut faire des tests sur une valeur qui dépend d'autres threads.

    Réponse longue : le problème de ta question, c'est que le programme ne sert à rien.

    Le thread qui retranche 1 au compteur s'il vaut 10 (autrement dit le fait passer à 9 s'il vaut 10,) c'est pas très intéressant. Avec de la chance il le fera peut-être une fois ou deux, puis très vite le premier thread fera monter la valeur à 11 et le second ne fera plus jamais rien.
    Je ne pense pas que ça puisse être utilisé dans une situation réelle.

    Du coup, il n'y a pas de précaution particulière à prendre, et vu que les effets ne sont pas exploitables de toute façon, au fond, pourquoi faire de la synchronisation, et même, pourquoi faire deux threads ?

    Normalement les blocs synchronized ne sont pas les seules manières de synchroniser.
    Quand on me parle de compteur, je pense plutôt "AtomicInteger" qui synchronise l'accès à sa valeur sans bloc synchronized.
    Ou on peut aussi juste déclarer le compteur comme volatile, c'est aussi une forme de synchronisation, qui propose moins de garantie que AtomicInteger ou un bloc synchronized, mais qui suffit dans certains cas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 26
    Par défaut
    C'est vrai que j'ai manqué d'imagination et que mon exemple n'était pas pertinent

    Je me demandais juste s'il lorsqu'on test la valeur d'une ressource critique, il fallait mettre ce test dans un bloc synchronized.

    La réponse est donc "Oui" ou bien "utilise un AtomicInteger".

    A propos de la méthode compareAndSet utilisable avec un AtomicInteger, il est écrit dans la doc :

    "
    public final boolean compareAndSet(int expect, int update)

    Atomically sets the value to the given updated value if the current value == the expected value.
    "


    Sans redéfinir la méthode equals(), est-ce que je peux utiliser la méthode ci-dessus comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    AtomicInteger a = new AtomicInteger();
     
    ....
     
    if(a.compareAndSet(10, a.getIntValue() - 1))


    Merci beaucoup !

  8. #8
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par Pacma Voir le message
    Je me demandais juste s'il lorsqu'on test la valeur d'une ressource critique, il fallait mettre ce test dans un bloc synchronized.

    La réponse est donc "Oui" ou bien "utilise un AtomicInteger".
    Ou bien "déclare le compteur volatile." Tout dépend de l'effet recherché.

    Citation Envoyé par Pacma Voir le message
    est-ce que je peux utiliser la méthode ci-dessus comme cela : [...]
    Non, car la valeur du compteur peut changer entre l'appel à a.getIntValue() et a.compareAndSet()
    De plus le if est devenu inutile.

    Ce serait plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    AtomicInteger a = new AtomicInteger();
     
    ....
     
    a.compareAndSet(10, 9);
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Synchronisation et accès concurrents
    Par Patrice Henrio dans le forum Langage
    Réponses: 2
    Dernier message: 07/08/2013, 12h12
  2. [concurrence] Choix entre différentes synchronisations
    Par dingoth dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 26/11/2009, 10h49
  3. [EJB] Accès concurrents à la base de données
    Par cameleon2002 dans le forum Java EE
    Réponses: 10
    Dernier message: 23/09/2003, 11h31
  4. Synchronisation de base de données locale/distante Internet
    Par StefC30 dans le forum Développement
    Réponses: 3
    Dernier message: 25/07/2003, 14h47

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