ProgrammationDéveloppeur Backend

Décrivez comment fonctionne le mot-clé synchronized en Java, dans quels cas l'utiliser et à quels problèmes son utilisation incorrecte peut-elle conduire ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Le mot-clé synchronized est présent dans Java depuis la prise en charge de la multithreading pour garantir un accès exclusif à des blocs de code ou des méthodes à partir de différents threads. Historiquement, c'est la réponse de Java aux problèmes classiques de race condition et de data inconsistency, qui surviennent lors d'accès simultanés à des données partagées à partir de différents threads.

Problème lors du travail avec la multithreading – garantir l'"atomicité" des opérations et empêcher des modifications contradictoires des états des objets. Une mauvaise utilisation de synchronized peut conduire à des blocages (deadlock), à une dégradation des performances ou même à une absence de synchronisation en cas de choix incorrect de l'objet-moniteur.

Solution – utiliser le mot-clé synchronized pour une méthode ou un bloc de code, où il est nécessaire de garantir qu'un seul thread exécute ce segment à la fois. Il faut choisir soigneusement l'objet de synchronisation, éviter de longues sections critiques, et pour des tâches plus complexes, utiliser des classes spéciales du paquet java.util.concurrent.

Exemple de code:

public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } } // Synchronisation de seulement une partie du code sur un objet distinct: private final Object lock = new Object(); public void complexIncrement() { synchronized (lock) { // section critique count++; } }

Caractéristiques clés :

  • synchronized bloque l'accès au code pour d'autres threads via le "moniteur" sélectionné
  • On peut synchroniser des méthodes entières ou seulement des blocs spécifiques
  • La synchronisation est un outil puissant mais risqué (deadlock, performance)

Questions pièges.

Quelle est la différence entre une méthode synchronized et un bloc synchronized ?

Une méthode synchronisée bloque le "moniteur" de l'objet (ou de la classe, si la méthode est static), un bloc synchronisé permet de spécifier explicitement l'objet-moniteur, ce qui offre plus de flexibilité.

Que se passe-t-il si plusieurs méthodes d'un même objet sont synchronisées ?

Si les deux méthodes sont marquées synchronized (pas static), les deux utilisent l'objet lui-même (this) comme moniteur. Un thread ne peut pas entrer dans l'une ou l'autre des méthodes tant qu'un autre y est présent.

Peut-on synchroniser des méthodes statiques et des méthodes non statiques ? Comment se débloquent-elles l'une par rapport à l'autre ?

Les méthodes statiques utilisent le moniteur de la classe elle-même (objet Class), les méthodes non statiques utilisent l'objet d'instance. Donc, une méthode synchronized statique et une méthode synchronized non statique ne se bloquent pas mutuellement.

Erreurs typiques et anti-patterns

  • Synchronisation sur un mauvais objet (par exemple, sur String ou un objet du pool)
  • Sections critiques trop longues ou obscures, entraînant une dégradation
  • Bouclage d'attente ou deadlock
  • Abus de synchronized au lieu d'utiliser des alternatives modernes de java.util.concurrent

Exemple de la vie réelle

Cas négatif

Un développeur synchronise des méthodes de différents objets, mais utilise partout le même String comme moniteur. Cela entraîne un ralentissement et des blocages "aléatoires" en raison de la réutilisation de chaînes du pool.

Avantages :

  • Le code est court, plus rapide à écrire

Inconvénients :

  • Risque élevé de blocages
  • Difficile à déboguer
  • Forte chute de performances

Cas positif

Synchronisation sur un objet final privé, qui est créé uniquement à l'intérieur de la classe (private final Object lock), et les sections critiques sont minimales en durée.

Avantages :

  • Garantie de comportement correct
  • Coûts minimaux
  • Bien lisible et maintenable

Inconvénients :

  • Nécessite de la discipline et de l'expérience
  • Pas toujours évident pour les développeurs débutants