Synchronisation

Synchronisation des threads

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

La notion de synchronisation peut être étrangère à des développeurs PHP qui doivent rarement se soucier de faire fonctionner deux éléments en parallèle. C'est pourquoi il est important pour eux de comprendre l'aspect de synchronisation en Java. L'aspect que cet article exploitera un peu plus.

Synchronized() et volatile

La première des deux autres moyens de synchronisation est le mot clé synchronized correspondant soit à une méthode, soit à un block. Il permet de coordonner l'exécution des méthodes et des variables. Grâce à lui, les Threads s'exécutent chronologiquement en garantissant la cohérence des données.

Autre moyen, le mot volatile indique qu'une variable doit être synchronisée. Autrement dit, elle ne peut pas être mis dans le cache local d'un Thread et qu'elle sera toujours lue depuis le Thread principal. Le mot volatile empêche donc le compilateur de modifier la logique d'exécution d'un traitement. Contrairement à synchronized, volatile ne bloque pas l'accès à la ressource synchronisée aux autres Threads. Il peut également agir sur les types primitifs tandis que synchronized non.

Cependant, il y a deux conditions qu'on doit remplir pour utiliser volatile dans la synchronisation :

  1. L'opération sur la variable ne peut pas dépendre de sa valeur actuelle : volatile ne peut pas être utilisé, par exemple, dans l'incrémentation d'un compteur.
  2. Ne peut pas participer dans l'opération de vérification (par exemple if-else) avec d'autres variables partagées.

Regardons deux exemples qui illustrent l'utilisation de ces deux méthodes de synchronisation. On commence avec synchronized :

afficher le code

Sur l'écran on voit l'exécution correcte :

Before incrementing 49
After incrementing 50


Before incrementing 50
After incrementing 51


Before incrementing 51
After incrementing 52


Before incrementing 52
After incrementing 53

Sans la synchronisation de la méthode increment() on risque de se trouver dans la situation où plusieurs Threads essaient d'y accéder avec la valeur d'int counter lue depuis le cache local. Voici l'exemple d'une exécution incorrecte :

Before incrementing 49




Before incrementing 50
After incrementing 50


Before incrementing 51
After incrementing 52
After incrementing 51
Before incrementing 50
After incrementing 53

Passons à l'illustration du volatile.

afficher le code

Grâce à volatile, les Threads sachent qu'il faut chercher boolean wasDone dans le Thread principal et non pas dans le cache respectif. Cependant, seule présence du volatile ne change pas grande chose. Seule sa relation avec synchronized peut garantir une meilleure coordination d'exécution.

Généralement, volatile est faiblement utilisé dans le monde des applications Java. Il est aussi peu documenté. Dans la plupart des cas, synchronized y est préféré pour une échelle plus grande de son utilisation. Dans nos exemples on suivra la tendence générale.

Un autre moyen de protéger des applications fonctionnant en mode multi-threading contre l'incohérence des données sont des objets immutables.

Bartosz KONIECZNY Concurrence

Une question ? Une remarque ?

*

*

Un conseil Symfony1

Comment inclure un template commun pour plusieurs modules ?

Le fichier à inclure (par exemple _menu.php) devrait être stocké dans le répertoire templates de l'application en question.

Ensuite, dans notre fichier de layout (par exemple layout.php), il suffit d'appeler le helper include_partial : Le répertoire global signifie que le template est global et n'appartient pas à un module particulier.