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 :

Y a-t-il une différence entre ces 3 exemples "atomiques" ?


Sujet :

Java

  1. #1
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 325
    Points : 3 766
    Points
    3 766
    Billets dans le blog
    12
    Par défaut Y a-t-il une différence entre ces 3 exemples "atomiques" ?
    Bonsoir,


    Je souhaiterais savoir s'il existe une différence entre ces trois exemples atomiques :
    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
    // Exemple 1 : synchronized
    public class MaClasse {
        public boolean maVariable = false;
     
        public void change(){
            synchronized(this){
                maVariable = true;
            }
        }
    }
     
     
    // Exemple 2 : type atomique
    public class MaClasse {
        public AtomicBoolean maVariable = new AtomicBoolean(false);
     
        public void change(){
            maVariable.set(true);
        }
    }
     
     
    // Exemple 3 : volatile
    public class MaClasse {
        public volatile boolean maVariable = false;
     
        public void change(){
            maVariable = true;
        }
    }
    S'il y a une différence, pouvez-vous m'expliquer pourquoi ?
    Je compte utiliser "maVariable" comme un flag, pour arrêter un thread qui tourne un boucle par exemple.


    Merci

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,



    Dans le cas précis il y a peu de différence, voir aucune.
    La synchronisation est inutile puisque les affectations sur les types 32bits ou moins sont atomique (en fait tout sauf long/double). En plus c'est même chiant car tu devras refaire une synchro à chaque fois que tu veux lire l'attribut...

    Si tu utilises directement le type boolean, il faut juste bien penser à positionner l'attribut en volatile comme tu l'a fait dans ton troisième exemple, afin d'éviter que la JVM n'optimise "trop" l'accès à cette variable.

    Le principal avantage des classe Atomic, c'est la présence des méthodes compareAndSet() et getAndSet() pour des opérations un peu plus avancées... mais sur des booléen l'utilité est moindre !
    Par contre les types Atomic* numériques ont plusieurs autres méthodes très utile, comme getAndIncrement(), getAndAdd(), incrementAndGet(), etc., qui garantissent un fonctionnement atomique.




    Après il faudra voir comme tu l'utilises aussi, et bien prendre en compte que la valeur peut changer à tout moment.


    a++

  3. #3
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 325
    Points : 3 766
    Points
    3 766
    Billets dans le blog
    12
    Par défaut
    Merci adiGuba

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Juste pour compléter : AtomicBoolean peut être utile dans certains cas où un traitement dépend de la valeur que l'on veut changer.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Demo {
    	private volatile boolean maVariable = true;
     
    	public void method() {
    		if (maVariable) {
    			maVariable = false;
    			// code qui doit être effectué une seule fois
    			System.out.println("CODE!!!");
    		}
    	}
    }
    En théorie le code à l'intérieur du if() ne doit être appelé qu'une seule et unique fois, puisqu'on met la valeur à false au début du if.
    Mais il y a là deux opérations atomiques : la lecture de "maVariable" dans la condition du if, puis son affectation dans la toute première instruction.

    Si plusieurs threads appellent cette méthode en même temps, on peut se retrouver dans un cas où plusieurs d'entre deux vérifient la condition du if et entrent dans le corps du if avant même que l'un d'entre eux n'ait positionné la variable à false... et donc le code sera exécuté plusieurs fois.
    Le cas est sûrement très rare... mais probable !



    AtomicBoolean permet de palier à cela avec compareAndSet() qui permet d'effectuer les deux opérations (vérification de la valeur + affectation) de manière atomique.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Demo {
     
    	private final AtomicBoolean maVariable = new AtomicBoolean(true);
     
    	public void method() {
    		if (maVariable.compareAndSet(true, false)) {
    			// code qui doit être effectué une seule fois, VRAIMENT !
    			System.out.println("CODE!!!");
    		}
    	}
    }

    a++

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    En fait, suite à mon précédent sujet, j'avais cru que le mot-clé volatile servait à rendre les opérations d'affectation atomiques pour tous (long, double, et les autres objets).

    Les 3 exemples que j'ai cités dans mon sujet n'étaient donc pas si équivalents que cela. Pour qu'ils le soient, j'aurais du, tout comme mon 3eme exemple (avec volatile boolean), mettre le mot-clé volatile à mon 1er exemple (avec boolean), et à mon 2nd exemple (avec AtomicBoolean), afin que la JVM ne cherche pas à mettre dans un cache d'optimisation ces attributs.
    Je réponds ici c'est mieux pour le suivi.


    Non tes exemples sont correct.

    Sur le premier, lorsque tu rentres dans un bloc synchronized, les caches sont vidés pour récupérer la dernière valeur. Il n'y a donc aucun soucis de ce genre.
    Tu utilises un bloc synchronized donc la JVM se doute bien que cela sera utilisé depuis différents threads

    Sur le second exemple, la référence AtomicBoolean pourrait éventuellement être stocké dans des caches différents.
    Mais comme tu ne modifies pas la référence mais la valeur de l'instance via set(), cela ne pose pas vraiment de soucis.
    A la rigueur tu pourrais juste déclarer l'attribut en final pour être sûr de ne pas changer sa référence par erreur...


    a++

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

Discussions similaires

  1. faire une différence entre deux tables
    Par geay dans le forum Langage SQL
    Réponses: 1
    Dernier message: 04/09/2006, 15h33
  2. [Dates] Calcul d'une différence entre deux heures
    Par loreleï85 dans le forum Langage
    Réponses: 12
    Dernier message: 28/06/2006, 11h43
  3. Réponses: 1
    Dernier message: 14/06/2006, 14h25
  4. [Type Sql] Quelles différences entre ces bases ?
    Par wonderboy dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 16/03/2006, 09h38

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