Le modèle singleton présente les caractéristiques suivantes :
1. Une classe singleton ne peut avoir qu’une seule instance.
2. Une classe singleton doit créer sa propre instance unique.
3. La classe singleton doit fournir cette instance à tous les autres objets.
Le modèle singleton garantit qu’il n’existe qu’une seule instance d’une classe, et il s’instancie et fournit cette instance à l’ensemble du système. Dans les systèmes informatiques, les pools de threads, les caches, les objets de journal, les boîtes de dialogue, les imprimantes et les objets pilotes de carte graphique sont souvent conçus comme des singletons. Ces applications disposent toutes plus ou moins des fonctionnalités de gestionnaires de ressources. Chaque ordinateur peut avoir plusieurs imprimantes, mais il ne peut y avoir qu'un seul spouleur d'imprimante pour empêcher que deux travaux d'impression ne soient envoyés simultanément sur l'imprimante. Chaque ordinateur peut avoir plusieurs ports de communication, et le système doit gérer ces ports de communication de manière centralisée pour empêcher qu'un port de communication soit appelé par deux requêtes en même temps. En bref, le but du choix du mode singleton est d'éviter les états incohérents et d'éviter les politiques à long terme.
Tout d’abord, examinons une implémentation singleton classique.
Copiez le code comme suit :
classe publique Singleton {
Singleton statique privé uniqueInstance = null ;
privé Singleton() {
// Existe uniquement pour vaincre l'instanciation.
}
public static Singleton getInstance() { if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance ;
}
// Autres méthodes...
}
Singleton évite que la classe soit instanciée en externe en limitant la méthode de construction à privée. Dans le cadre de la même machine virtuelle, la seule instance de Singleton n'est accessible que via la méthode getInstance(). (En fait, il est possible d'instancier une classe avec un constructeur privé via le mécanisme de réflexion Java, ce qui invalidera fondamentalement toutes les implémentations Java singleton. Ce problème ne sera pas abordé ici. Supposons que le mécanisme de réflexion n'existe pas. .)
Cependant, l’implémentation ci-dessus ne prend pas en compte les problèmes de sécurité des threads. Ce qu'on appelle la sécurité des threads signifie que si plusieurs threads s'exécutent en même temps dans le processus où se trouve votre code, ces threads peuvent exécuter ce code en même temps. Si les résultats de chaque exécution sont les mêmes que ceux des exécutions monothread et que les valeurs des autres variables sont les mêmes que celles attendues, cela est thread-safe. En d'autres termes : l'interface fournie par une classe ou un programme est une opération atomique pour les threads ou le basculement entre plusieurs threads ne provoquera pas d'ambiguïté dans les résultats d'exécution de l'interface, ce qui signifie que nous n'avons pas besoin de prendre en compte les problèmes de synchronisation. De toute évidence, l'implémentation ci-dessus ne répond pas aux exigences de sécurité des threads et plusieurs instances Singleton sont susceptibles d'apparaître dans un environnement simultané.
Copiez le code comme suit :
//Classe singleton de style affamé. Elle a été instanciée par elle-même lorsque la classe est initialisée.
classe publique Singleton1 {
//Constructeur privé par défaut
privé Singleton1() {}
//Déjà instancié par lui-même
private static final Singleton1 single = new Singleton1();
//méthode de fabrique statique
public statique Singleton1 getInstance() {
retourner seul ;
}
}
//Classe singleton paresseuse Instancier lorsqu'elle est appelée pour la première fois.
classe publique Singleton2 {
//Constructeur privé par défaut
privé Singleton2() {}
//Remarque, il n'y a pas de finale ici
privé statique Singleton2 single=null ;
//méthode de fabrique statique
public synchronisé statique Singleton2 getInstance() {
si (simple == nul) {
unique = nouveau Singleton2();
}
retourner seul ;
}
}