L’exclusion mutuelle
Chaque fois que plusieurs threads s’exécutent en même temps, il faut prendre des précautions concernant leur bonne exécution. Par exemple, si deux threads veulent modifier la même variable, il ne faut pas qu’ils le fassent en même temps.
Java offre un système simple et efficace pour réaliser cette tâche. Si une méthode déclarée avec le mot clé synchronized est déjà en cours d’exécution, alors les threads qui en auraient également besoin doivent attendre leur tour.
Le mécanisme d’exclusion mutuelle en Java est basé sur le moniteur. Pour définir une méthode protégée, afin de s’assurer de la cohérence des données, il faut utiliser le mot clé synchronized. Cela crée à l’exécution, un moniteur associé à l’objet qui empêche les méthodes déclarées synchronized d’être utilisées par d’autres objets dès lors qu’un objet utilise déjà une des méthodes synchronisées de cet objet. Dès l’appel d’une méthode synchronisée, le moniteur verrouille tous les autres appels de méthodes synchronisées de l’objet. L’accès est de nouveau automatiquement possible dès la fin de l’exécution de la méthode.
Ce procédé peut bien évidemment dégrader les performances lors de l’exécution mais il garantit, dès lors qu’il est correctement utilisé, la cohérence des données.
La sécurisation d’une méthode
Lorsque l’on crée une instance d’une classe, on crée également un moniteur qui lui est associé. Le modificateur synchronized place la méthode (le bloc de code) dans ce moniteur, ce qui assure l’exclusion mutuelle.
La méthode ainsi déclarée ne peut être exécutée par plusieurs processus simultanément. Si le moniteur est occupé, les autres processus seront mis en attente. L’ordre de réveil des processus pour accéder à la méthode n’est pas prévisible.
Si un objet dispose de plusieurs méthodes synchronized, ces dernières ne peuvent être appelées que par le thread possédant le verrou sur l’objet.
La sécurisation d’un bloc
L’utilisation de méthodes synchronisées trop longues à exécuter peut entrainer une baisse d’efficacité lors de l’exécution. Avec java, il est possible de placer n’importe quel bloc de code dans un moniteur pour permettre de réduire la longueur des sections de code sensibles.
synchronized void methode1() {
// bloc de code sensible
…
}
void methode2(Object obj) {
…
synchronized (obj) {
// bloc de code sensible
…
}
}
L’objet dont le moniteur est à utiliser doit être passé en paramètre de l’instruction synchronized .
La sécurisation de variables de classes
Pour sécuriser une variable de classe, il faut un moniteur commun à toutes les instances de la classe. La méthode getClass() retourne la classe de l’instance dans laquelle on l’appelle. Il suffit d’utiliser un moniteur qui utilise le résultat de getClass() comme verrou.
……
Le multitâche (276 KO) (Cours PDF)