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 :

Principe de synchronisation avec synchronized


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Développeur Back-End
    Inscrit en
    Avril 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Back-End

    Informations forums :
    Inscription : Avril 2006
    Messages : 44
    Par défaut Principe de synchronisation avec synchronized
    Bonjour tous le monde,

    j'avoue ne pas bien comprendre le fonctionnement de la synchronisation multi-thread, j'ai beau lire les explications sur le net mais plus j'en lie plus je m'embrouille la tête et moins je comprend.

    Bref j'ai quelques questions à vous poser :

    J'ai cru comprendre que l'on pouvait ce synchroniser directement sur une variable objet comme String, Integer, etc...
    Ce bout de code est-il correcte car apparemment pour manipuler une variable static il faut ce synchroniser sur un this.getClass() et je ne comprend pas pourquoi (une object static est pourtant identique quelque soit la classe qui l'utilise, non ?).

    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
     
    public class maclasse {
        private static Integer mavariableA = 0;
        private static Integer mavariableB = 0;
     
        public static void addA() {
            synchronized(mavariableA) {
                mavariableA++;
            }
        }
     
        public static void dellA() {
            synchronized(mavariableA) {
                mavariableA--;
            }
        }
     
        public static Integer getA() {
            synchronized(mavariableA) {
                return mavariableA;
            }
        }
     
        public static void addB() {
            synchronized(mavariableB) {
                mavariableB++;
            }
        }
     
        public static void dellB() {
            synchronized(mavariableB) {
                mavariableB--;
            }
        }
     
        public static Integer getB() {
            synchronized(mavariableB) {
                return mavariableB;
            }
        }
    }
    J'ai lu aussi qu'il ne fallait pas synchroniser sur un Boolean, mais Boolean est un objet non ?

    Bref j'y pige pas grand chose

    Merci d'avance pour votre aide

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    a la base, si il ne s'agissait pas d'un type pour lequel le compilateur fait de n'auto-boxingn vous n'auriez pas de problème. Seulement, ici, il faut être conscient que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public static void addA() {
            synchronized(mavariableA) {
                mavariableA++;
            }
        }
    va être transformé par le compilateur en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        public static void addA() {
            synchronized(mavariableA) {
                int temp = mavariableA.intValue();
                temp++;
                maVariableA=Integer.valueOf(temp);
            }
        }
    Autrement dit, l'instance sur laquelle se fait le verrou ne sera pas la même pour tous les monde, donc le verrou ne sert plus à rien (il ne verrouille plus rien)

    Dans votre cas, il faut soit créer une variable séparée servant de verrou:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Integer maVariableA=0;
    Object monVerrouA = new Object();
        public static void addA() {
            synchronized(monVerrouA) {
                mavariableA++;
            }
        }
    soit utiliser la classe directement via un de ces deux code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        public static void addA() {
            synchronized(maclasse.class) {
                mavariableA++;
            }
        }
        public static synchronized addA() {
                mavariableA++;;
        }

  3. #3
    Membre averti
    Profil pro
    Développeur Back-End
    Inscrit en
    Avril 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Back-End

    Informations forums :
    Inscription : Avril 2006
    Messages : 44
    Par défaut
    l'auto boxing ? jamais entendu parlé de cela auparavant, en tout cas c'est clair comme ça, merci.

    Lorsque que l'on fait un synchronized sur une méthode, on pose un verrou sur l'ensemble des méthodes synchronisées de la classe ? Donc si je veux manipuler plusieurs variables il est préférable de synchroniser directement sur le code en utilisant un verrou unique par variable évitant ainsi les autres thread de patienter pour manipuler d'autres variables ?

    Si je synchronise des Map, le problème disparait ?

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par callapa Voir le message
    l'auto boxing ? jamais entendu parlé de cela auparavant, en tout cas c'est clair comme ça, merci.
    C'est le fait de pouvoir indifférement utiliser soit des objets soit des type des bases (int,long,double,float,boolean), ca existe depuis java 5

    Lorsque que l'on fait un synchronized sur une méthode, on pose un verrou sur l'ensemble des méthodes synchronisées de la classe ? Donc si je veux manipuler plusieurs variables il est préférable de synchroniser directement sur le code en utilisant un verrou unique par variable évitant ainsi les autres thread de patienter pour manipuler d'autres variables
    exact
    Si je synchronise des Map, le problème disparait ?
    les maps ne sont pas des types de base donc tant que tu ne remplace pas explicitement ta map par une autre, elle peux servir de base à un verrou. Cependant, pour les maps, comme tout objet de type collection, il existe déjà des implémentation synchronisées accessible via Collections.synchronizedMap(autreMap)

  5. #5
    Membre averti
    Profil pro
    Développeur Back-End
    Inscrit en
    Avril 2006
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Back-End

    Informations forums :
    Inscription : Avril 2006
    Messages : 44
    Par défaut
    J'ai toutes les réponses à mes questions, merci pour ton aide précieuse tchize_

  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
    Citation Envoyé par callapa Voir le message
    J'ai lu aussi qu'il ne fallait pas synchroniser sur un Boolean, mais Boolean est un objet non ?
    Là n'est pas la question : ça compile très bien si on le fait, mais ça ne fait pas ce qu'on croit.

    Ce n'est pas seulement avec Boolean d'ailleurs, c'est pareil avec tous les types box : Boolean, Byte, Short, Character, Integer, Long, Float et Double. Avec d'autres types, comme String, aussi, pour raisons similaires.

    Pour les Booleans, il n'existe que deux instances différentes : TRUE et FALSE. Supposons par exemple que tu synchronises un bout de code sur TRUE. Ce sera le même TRUE utilisé ici, que partout ailleurs dans toute ton application ! Absolument toutes les synchronisations sur TRUE seront mutuellement exclusives, absolument partout ! Des millions de bouts de code qui n'ont rien à voir les uns avec les autres deviennent mutuellement exclusifs, sans qu'on s'en rende compte.

    Bon, c'est pas tout-à-fait vrai : il est possible de créer une nouvelle instance de Boolean avec new Boolean()... Mais c'est inutile puisque qu'il n'existe que deux valeurs utiles, true et false, et qu'il y a déjà deux instances pour les représenter, TRUE et FALSE. Personne n'en crée jamais d'autre, à moins d'être débutant ou d'avoir une raison profonde et sûrement mauvaise.

    La même chose s'applique pour la plupart des types de ce genre. Toutes les instances d'Integer ne sont pas déjà créées, mais les 256 premières, si. Et puis, la JVM peut très bien décider de réutiliser les autres au fur et à mesure qu'elles sont créées.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    en résumé, pas de lock sur un objet immuable, puisque quand on changera sa valeur, on changera d'instance :p

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 12/01/2007, 10h07
  2. Synchronisation Avec LDAP
    Par Patrick31 dans le forum Access
    Réponses: 1
    Dernier message: 24/10/2006, 18h04
  3. [SQL2K] : Synchronisation avec d'autres bases de données
    Par zalalus dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 21/07/2006, 17h07
  4. Thread Synchronisation avec structure FIFO ??
    Par vincedom dans le forum MFC
    Réponses: 5
    Dernier message: 30/03/2006, 06h00
  5. [VB.NET] DataGridView et synchronisation avec une BD
    Par tidan dans le forum Windows Forms
    Réponses: 3
    Dernier message: 02/02/2006, 11h12

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