Le Touilleur ExpressLe Touilleur ExpressLe Touilleur ExpressLe Touilleur Express
  • Accueil
  • A propos de l’auteur
  • A propos du Touilleur Express

Quelle est la différence entre volatile et synchronized ?

    Home Java Quelle est la différence entre volatile et synchronized ?

    Quelle est la différence entre volatile et synchronized ?

    Par Nicolas Martignole | Java | 3 commentaires | 9 décembre, 2010 | 0 | 49 585 affichages
         

    Credit photo mstcweb licence Commons CreativeLors d’un entretien d’évaluation en mai dernier pour le compte d’une grande banque, la personne en face de moi me demande la différence entre volatile et synchronized. J’avoue que je n’ai pas répondu tout à fait correctement. Voici donc quelques éléments de réponses, il est toujours bon d’apprendre quelque chose.

    Avant tout vous ne serez amené à utilisez synchronized et volatile qu’à de rares occasions si vous travaillez sur une bonne vieille application de gestion. Vu la qualité de certaines API comme Google Guava, mon premier conseil est le suivant : soyez humble. Allez voir un peu sur Internet les dernières nouveautés de ces API plutôt que de vous lancer dans du développement d’application parallèle.

    Depuis Java 5 la définition formelle du mot clé volatile a un peu changé. Dans cet article de Brian Goetz de 2004 sur la JSR-133, Brian présente la différence d’approche sur le modèle mémoire de la JVM. Cela me rappelle un article sur le pattern Double-checked locking dont j’ai parlé il y a 5 ans sur le Touilleur Express. En quelques mots, le mot clé volatile permet de signifier à la JVM qu’une variable sera modifiée par plusieurs Threads. En déclarant une variable volatile, sa valeur ne sera jamais placée dans le cache local à la Thread courante d’exécution. Chaque lecture et chaque écriture passeront forcément par la mémoire partagée entre les Threads. De fait, l’accès à la variable elle-même devient implicitement synchronisé. Et ce, bien plus efficacement qu’avec un marqueur synchronized sur des méthodes.

    C’est de la synchronisation implicite, tout du moins vu de l’oeil du programmeur. Les subtilités de la JVM et le modèle mémoire sont un peu plus complexe que cela. Si nous voulions comparer ces 2 opérateurs, nous pourrions dire que synchronized s’applique uniquement à des Objets alors que volatile peut s’utiliser aussi sur des types primitifs.

    Le tableau suivant tiré de cet article résume les différences entre synchronized et volatile :

    Characteristic Synchronized Volatile
    Type of variable Object Object or primitive
    Null allowed? No Yes
    Can block? Yes No
    All cached variables synchronized on access? Yes From Java 5 onwards
    When synchronization happens When you explicitly enter/exit a synchronized block Whenever a volatile variable is accessed.
    Can be used to combined several operations into an atomic operation? Yes Pre-Java 5, no. Atomic get-set of volatiles possible in Java 5.
    Difference between synchronized and volatile

    Le mot clé volatile ne rend pas l’accès bloquant pour une Thread, comme le fait synchronized. Ce n’est donc pas une solution pour faire un sémaphore, une barrière, bref des patterns d’inter-lockages de Threads. Un accès à une variable volatile ne peut pas bloquer une Thread. Alors que synchronized s’applique à un objet, volatile s’applique à la référence d’un objet… qui peut être null. C’est bien l’accès à la référence qui est garantis.

    Au quotidien vous ne verrez que très rarement finalement le mot clé volatile. Ce que l’on voit dans les APis par contre, c’est des types comme AtomicInteger ou sinon des décorateurs complexes comme AtomicReference.

    Par expérience donc, je vous recommande plutôt de faire confiance à des APIs publiques et open-source plutôt que de vous lancer dans l’utilisation de ces types complexes. Si vous travaillez sur une API, allez-y. Mais si vous travaillez sur un projet que quelqu’un doit pouvoir maintenir facilement, évitez de vous lancer dans l’implémentation de tout ce qui tourne autour de la synchronisation.

    Et donc au prochain entretien que j’aurai, si je ne sais pas répondre je pourrai au moins dire : « et vous avez vu sinon l’article sur le blog le Touilleur Express ? Et bien c’est moi qui l’ai écrit »

    Références
    http://www.javamex.com/tutorials/synchronization_volatile.shtml
    http://www.flickr.com/photos/mstcweb/3550301596/sizes/m/in/photostream/ Photo trouvée sur FlickR, libre de droits en licence Commons Creatives, prise par mstcweb.

    Articles similaires:

    Default ThumbnailQuelle est la différence entre un Iterator et une Enumeration ? Default ThumbnailUSI 2009 : l’ergonomie entre forme et fonction, une recette par l’exemple Default ThumbnailSynchronisation avec Vector,Hashtable,HashMap et ArrayList Default ThumbnailSoirée Paris JUG sur Java Avancé
    No tags.
    • Avatar
      lucdew 10 décembre 2010 at 2 h 51 min

      A propos du Double Check Locking pattern, je vous invite à lire cet article : http://www.nabeelalimemon.com/blog/2010/11/double-check-locking-pattern-is-not-broken-any-more/
      Même si personnellement je ne l’utilise pas (par habitude), le DCL pattern avec un « volatile » ne pose plus de problème depuis l’introduction de la JSR 133 (incluse dans le JDK 1.5) .

    • Avatar
      David Martin 10 décembre 2010 at 21 h 08 min

      Certaines subtilités sont aussi à noter pour éviter certains pieges pas facile à débusquer, comme la non atomicité d’opérations comme les increments/decrements presque anodins que sont ++ et –. Une variable volatile ne garantira en aucun cas l’atomicité d’une telle opération sur elle, et cela conduira à des comportements difficle à cerner. Un synchronized lui le pourra, ou l’usage de l’API concurrent(.atomic)

      On ne peut pas toujours éviter d’avoir à traiter des cas d’accès concurrents, et ce même sans développer des API. Je ne pense pas donc qu’il faille en décourager l’écriture, mais plutôt en encourager l’apprentissage. Ainsi ces notions seront utilisées aux bons endroits de la bonne façon.

      My 2 cts 😉

    • Avatar
      Sylvain 15 décembre 2010 at 15 h 58 min

      Completement d’accord avec David… lorsqu’on a à développer une appli avec du multithreading, je vois mal comment on peut s’en sortir si de base on n’a pas saisit et compris ces deux mots clés… (c’est pas évident, j’avoue que je m’y perds).

    Recent Posts

    • Podcast à (re)découvrir

      On me demande parfois comment faire sa veille technologique… je suis assez

      20 janvier, 2021
    • Lorsque le réseau social Parler cherche un nouvel endroit pour poser ses encombrantes valises…

      Nous allons parler architecture et plus exactement, du nombre de machines nécessaires

      19 janvier, 2021
    • Veille technologique janvier 2021

      Nouveau format d’article cette semaine : je vous propose de partager mes

      17 janvier, 2021

    Recent Tweets

    • RT  @welovedevs : On lui a demandé s'il pensait que les développeurs étaient considérés dans son entreprise. Voilà ce qu'il a répondu 😩 #Enqu…

      3 hours ago
    • Lunatech a aussi eu l'excellente idée de devenir partenaire avec le projet FP Tower, et cela permettra à tous les e… https://t.co/wMfT5MhviI

      4 hours ago
    • Le site https://t.co/r90vLjZTQt propose un cours d'introduction sur la prog fonctionnelle avec Scala. La qualité de… https://t.co/cwOyzNhL0N

      4 hours ago
    • RT  @JulienTruffaut : I am so happy of this partnership. Lunatech is a fantastic IT consultancy which invests a lot in the training of its em…

      4 hours ago
    •  @k33g_org   @fcamblor   @waxzce   @bluxte  On a un Channel slack pour le hackbreakfast que nous organisions avant les conf… https://t.co/JfTJ2BAMlP

      9 hours ago

    Mots clés

    agile (18) ajax (11) Apple (11) architecture (5) barcamp (5) BarCampJavaParis (5) ddd (5) devoxx (33) esb (6) exo (6) flex (9) geek (5) google (11) grails (5) groovy (10) humeur (12) humour (7) independant (6) iphone (12) Java (76) javascript (7) jazoon (28) jboss (22) jboss seam (12) jsf (9) jug (16) Linux (11) mac (6) mule (5) parisjug (7) paris jug (22) pjug (6) play (8) playframework (6) portlet (5) ria (8) Scala (19) scrum (44) spring (23) Startup (10) twitter (5) usi (21) usi2010 (9) web (16) xebia (7)

    Le Touilleur Express

    Contactez-moi : nicolas@touilleur-express.fr

    Suivez-moi sur Twitter : @nmartignole

    Copyright© 2008 - 2020 Nicolas Martignole | Tous droits réservés
    • A propos de l’auteur
    • A propos du Touilleur Express
    Le Touilleur Express