mot-clé synchronisé en Java
Le mot-clé synchronized
en Java contrôle l'accès aux ressources partagées entre plusieurs threads. Il garantit qu'un seul thread peut exécuter un bloc ou une méthode synchronisé(e) à la fois, ce qui évite les interférences entre les threads et garantit la cohérence de la mémoire.
Utilisation
Le mot-clé synchronized
peut être appliqué à des méthodes ou à des blocs dans des méthodes. Lorsqu'une méthode ou un bloc est déclaré comme étant synchronisé, un verrou est obtenu sur l'objet spécifié et les autres threads ne peuvent pas accéder au code synchronisé tant que le verrou n'est pas libéré.
Syntax
Méthode synchronisée
public synchronized void synchronizedMethod() {
// method code
}
Bloc synchronisé
public void method() {
synchronized (object) {
// synchronized code
}
}
object
: L'objet sur lequel la synchronisation doit être effectuée. Il s'agit généralement de l'instance actuelle (this
) ou d'un objet spécifique.
Exemples
Exemple 1 : Méthode synchronisée
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
public static void main(String[] args) {
Counter counter = new Counter();
// Create multiple threads to increment the counter
Thread t1 = new Thread(() -> counter.increment());
Thread t2 = new Thread(() -> counter.increment());
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final count: " + counter.getCount());
}
}
Dans cet exemple, la méthode increment
est synchronisée, ce qui garantit qu'un seul thread peut incrémenter le compteur à la fois, évitant ainsi les conditions de course.
Exemple 2 : Bloc synchronisé
public class SynchronizedBlockExample {
private final Object lock = new Object();
private int count = 0;
public void increment() {
synchronized (lock) {
count++;
}
}
public int getCount() {
return count;
}
public static void main(String[] args) {
SynchronizedBlockExample example = new SynchronizedBlockExample();
// Create multiple threads to increment the counter
Thread t1 = new Thread(() -> example.increment());
Thread t2 = new Thread(() -> example.increment());
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Final count: " + example.getCount());
}
}
Cet exemple utilise un bloc synchronisé pour contrôler l'accès à la variable count
. L'objet de verrouillage garantit qu'un seul thread peut exécuter le bloc synchronisé à la fois.
Conseils et bonnes pratiques
- Réduire au minimum le code synchronisé: Les blocs synchronisés doivent être aussi courts que possible afin de réduire les conflits et d'améliorer les performances.
- Utilisez les objets finaux: Lorsque vous utilisez des blocs synchronisés, utilisez des objets finaux comme verrous pour garantir la cohérence.
- Évitez les synchronisations imbriquées: Les blocs synchronisés imbriqués peuvent entraîner des blocages. Évitez-les ou utilisez-les avec prudence.
- Utilisez des collections simultanées: Pour une synchronisation complexe, envisagez d'utiliser les collections concurrentes du paquetage
java.util.concurrent
, telles queConcurrentHashMap
, qui fournissent une synchronisation intégrée. - Volatile Mot-clé: Pour les variables auxquelles accèdent plusieurs threads, mais qui ne nécessitent pas de synchronisation complexe, envisagez d'utiliser le mot-clé
volatile
pour garantir la visibilité.
private volatile boolean flag;
- Sécurité du fil: Veillez toujours à ce que les ressources partagées soient correctement synchronisées afin de maintenir la sécurité des threads et d'éviter la corruption des données.
- Méthodes statiques synchronisées: Synchronisez les méthodes statiques afin d'assurer un accès synchronisé au niveau de la classe, en veillant à ce qu'un seul thread puisse exécuter la méthode statique dans toutes les instances.
public static synchronized void staticMethod() {
// method code
}
- Réentrance: Les verrous intrinsèques de Java sont réentrants, ce qui signifie que si un thread détient un verrou, il peut l'acquérir à nouveau sans se bloquer lui-même.