1. Singleton affamé à la chinoise
Copiez le code comme suit :
classe publique Singleton {
Private final statique Singleton INSTANCE = new Singleton();
privé Singleton() { }
public statique Singleton getInstance() {
retourner INSTANCE ;
}
}
2. Avec l'aide de cours internes
Il s'agit d'un singleton paresseux car le mécanisme Java stipule que la classe interne SingletonHolder ne sera chargée (implémentée paresseuse) que lorsque la méthode getInstance() est appelée pour la première fois, et son processus de chargement est thread-safe. L'instance est instanciée une fois lorsque la classe interne est chargée.
Copiez le code comme suit :
classe publique Singleton {
privé Singleton() { }
classe statique privée SingletonHolder {
Private final statique Singleton INSTANCE = new Singleton();
}
public statique Singleton getInstance() {
retourner SingletonHolder.INSTANCE ;
}
}
3. Solution de verrouillage ordinaire
Copiez le code comme suit :
classe publique Singleton {
Instance Singleton statique privée = null ;
privé Singleton() { }
public statique synchronisé Singleton getInstance() {
si (instance == null) {
instance = nouveau Singleton();
}
instance de retour ;
}
}
Bien que le problème de sécurité des threads soit résolu, chaque thread appelant getInstance doit être verrouillé uniquement la première fois que getInstance est appelé. Veuillez consulter la solution de double détection ci-dessous.
4. Double détection, mais faites attention à la méthode d'écriture
Copiez le code comme suit :
classe publique Singleton {
Instance Singleton statique privée = null ;
privé Singleton() { }
public statique Singleton getInstance() {
si (instance == null) {
synchronisé (Singleton.class) {
Température singleton = instance ;
si (temp == nul) {
temp = nouveau Singleton();
instance=temp
}
}
}
instance de retour ;
}
}
En raison du problème de réorganisation des instructions, il ne peut pas être écrit directement comme suit :
classe publique Singleton {
Instance Singleton statique privée = null ;
privé Singleton() { }
public statique Singleton getInstance() {
si (instance == null) {
synchronisé (Singleton.class) {
si (instance == null) {
instance = nouveau Singleton();
}
}
}
instance de retour ;
}
}
Mais si la variable d'instance est modifiée avec volatile, tout ira bien. Si elle est modifiée avec volatile, cela peut garantir que les instructions correspondantes de instance = new Singleton(); sûr:
classe publique Singleton {
Instance Singleton volatile statique privée = null ;
privé Singleton() { }
public statique Singleton getInstance() {
si (instance == null) {
synchronisé (Singleton.class) {
si (instance == null) {
instance = nouveau Singleton();
}
}
}
instance de retour ;
}
}