Leçon 47 : Synchronisation et problèmes de sécurité des threads
Lorsque plusieurs threads accèdent simultanément à des données partagées et mutables, cela peut entraîner des résultats incohérents et une corruption des données—une condition connue sous le nom de race condition (condition de concurrence).
1. Le problème de la Race Condition
Considérons deux threads essayant d'incrémenter un compteur partagé (i++). Cette opération implique trois étapes :
- Lire la valeur actuelle de
i. - Incrémenter la valeur.
- Écrire la nouvelle valeur dans
i.
Si le Thread A lit i=10, le Thread B lit i=10, que les deux incrémentent à 11, et que les deux réécrivent 11, le résultat final est 11 au lieu du 12 correct.
2. Synchronisation (Le mot-clé synchronized)
La Synchronisation est l'outil utilisé pour contrôler l'accès aux ressources partagées, garantissant qu'un seul thread peut exécuter une section critique de code à la fois.
Méthodes synchronisées
L'application de synchronized à une méthode verrouille toute l'instance de l'objet. Si le Thread A appelle une méthode synchronisée, aucun autre thread ne peut entrer dans une autre méthode synchronisée sur ce même objet tant que le Thread A n'en est pas sorti.
java public class SharedCounter { private int count = 0;
// Un seul thread peut être à l'intérieur de cette méthode à tout moment
public synchronized void increment() {
count++; // Section critique
}
}
Blocs synchronisés
C'est plus granulaire. Cela permet une synchronisation uniquement sur un bloc de code spécifique, réduisant la contention en verrouillant un objet spécifique (le moniteur).
java public void process() { // Opérations non critiques ici
synchronized (this) { // Verrouille uniquement la section critique
// Code critique qui modifie les ressources partagées
count++;
}
// Autres opérations non critiques
}
Le Moniteur : Chaque objet Java possède un verrou intrinsèque (moniteur). La synchronisation fonctionne en acquérant et en relâchant ce verrou.