Accéder au contenu principal
Documents
Tableaux JavaProgrammation orientée objet en JavaTraitement des fichiers en JavaIntroduction To JavaLes bases du langage JavaMots-clés Java

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 que ConcurrentHashMap, 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.

Apprendre l'essentiel de Java

Développez vos compétences en Java à partir de la base et maîtrisez les concepts de programmation.
Commencez à apprendre gratuitement