Singleton : implémentations sûres vis-à-vis des threads
Créez un Singleton sûr vis-à-vis des threads avec le verrouillage à double vérification, une énumération ou le modèle holder.
Singleton : implémentations sûres vis-à-vis des threads est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.
Le modèle singleton
Le singleton garantit qu’une seule instance d’une classe existe dans la JVM. Parmi les cas d’utilisation courants figurent les gestionnaires de configuration, les pools de connexions et les services de journalisation.
Singleton naïf — non sûr en environnement multithread
Le singleton différé classique échoue en cas d’accès concurrent : deux threads peuvent franchir simultanément le contrôle de valeur nulle et créer deux instances.
public class Config {
private static Config instance;
private Config() {}
public static Config getInstance() {
if (instance == null) { // race condition!
instance = new Config();
}
return instance;
}
}Méthode synchronisée — simple mais lente
Ajouter synchronized à getInstance() garantit la sécurité des accès concurrents, mais verrouille chaque appel, même une fois l’instance créée, ce qui entraîne une surcharge inutile.
public static synchronized Config getInstance() {
if (instance == null) instance = new Config();
return instance;
}Verrouillage à double vérification
Effectuez une vérification sans verrou, puis vérifiez à nouveau dans un bloc synchronized. Le champ doit être déclaré volatile pour empêcher la réorganisation des instructions.
public class Config {
private static volatile Config instance;
private Config() {}
public static Config getInstance() {
if (instance == null) {
synchronized (Config.class) {
if (instance == null) instance = new Config();
}
}
return instance;
}
}Initialisation différée avec Holder
Il s’agit du singleton différé le plus sûr et le plus efficace : une classe imbriquée statique privée contient l’instance. La JVM ne la charge que lors du premier appel à getInstance() ; le chargement des classes est intrinsèquement sûr en environnement multithread.
public class Config {
private Config() {}
private static final class Holder {
static final Config INSTANCE = new Config();
}
public static Config getInstance() {
return Holder.INSTANCE;
}
}Singleton avec une énumération
Effective Java recommande une énumération comportant une seule constante. Cette solution est concise, sûre en environnement multithread, sûre lors de la sérialisation et immunisée contre les attaques par réflexion.
public enum AppConfig {
INSTANCE;
private String apiUrl = "https://api.example.com";
public String getApiUrl() { return apiUrl; }
}
// Usage:
String url = AppConfig.INSTANCE.getApiUrl();Initialisation immédiate
Si le coût au démarrage est acceptable, initialisez l’instance lors du chargement de la classe avec un champ static final. La solution est simple et sûre en environnement multithread, mais l’instance est toujours créée, même si elle n’est jamais utilisée.
public class Config {
private static final Config INSTANCE = new Config();
private Config() {}
public static Config getInstance() { return INSTANCE; }
}Singleton et sérialisation
Un singleton sérialisé puis désérialisé produit une nouvelle instance, sauf si vous ajoutez readResolve() en retournant INSTANCE. L’approche par énumération gère automatiquement ce cas.
private Object readResolve() { return INSTANCE; }Singleton et attaques par réflexion
La réflexion peut invoquer des constructeurs privés. Pour vous en protéger, lancez une exception dans le constructeur si une instance existe déjà. Les singletons fondés sur une énumération sont immunisés selon les spécifications de la JVM.
private Config() {
if (Holder.INSTANCE != null) {
throw new IllegalStateException("Use getInstance()");
}
}Singleton dans les infrastructures d’injection de dépendances
Dans Spring, les composants sont des singletons par défaut (@Scope("singleton")). Vous implémentez rarement le modèle singleton manuellement ; laissez le conteneur DI le gérer.
@Component // Spring manages a single instance
public class FeatureFlags {
private final boolean darkMode = true;
public boolean isDarkMode() { return darkMode; }
}Tester les singletons
Les singletons sont difficiles à tester unitairement, car ils portent un état global. Préférez l’injection de dépendances au code singleton manuel ; injectez des instances simulées dans vos vérifications par injection de constructeur.
Vérification rapide
Quelle approche du singleton est recommandée dans Effective Java ?
Récapitulatif
Pour des singletons sûrs en environnement multithread, utilisez l’approche du conteneur Holder à initialisation différée ou celle de l’énumération. Évitez l’initialisation différée naïve. Dans les applications Spring, laissez l’infrastructure gérer la portée.
Questions Fréquemment Posées
La leçon « Singleton : implémentations sûres vis-à-vis des threads » est-elle gratuite ?
Oui — le texte complet de « Singleton : implémentations sûres vis-à-vis des threads » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Singleton : implémentations sûres vis-à-vis des threads » ?
Créez un Singleton sûr vis-à-vis des threads avec le verrouillage à double vérification, une énumération ou le modèle holder. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Java Academy ?
Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Singleton : implémentations sûres vis-à-vis des threads » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?
Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Singleton : implémentations sûres vis-à-vis des threads
- Modèle de méthode de fabrique
- Fabrique abstraite pour des familles de produits
- Modèle Builder avec API fluide