Wie lässt sich ein Singleton-Entwurfsmuster in Java effizient implementieren?
Antworten
Zu viele Anzeigen?Ich benutze die Spring Framework um meine Singles zu verwalten.
Es erzwingt nicht die "Singleton-ness" der Klasse (was man sowieso nicht wirklich tun kann, wenn mehrere Klassenlader beteiligt sind), aber es bietet eine wirklich einfache Möglichkeit, verschiedene Fabriken für die Erstellung verschiedener Objekttypen zu erstellen und zu konfigurieren.
Wenn Sie kein "Lazy Loading" benötigen, versuchen Sie es einfach:
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() { return Singleton.INSTANCE; }
protected Object clone() {
throw new CloneNotSupportedException();
}
}
Wenn Sie träges Laden wünschen und Ihr Singleton thread-sicher sein soll, versuchen Sie es mit dem Double-Checking-Muster:
public class Singleton {
private static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if(null == instance) {
synchronized(Singleton.class) {
if(null == instance) {
instance = new Singleton();
}
}
}
return instance;
}
protected Object clone() {
throw new CloneNotSupportedException();
}
}
Da das Double-Checking-Muster nicht garantiert funktioniert (aufgrund eines Problems mit Compilern, ich weiß nichts mehr darüber), könnten Sie auch versuchen, die gesamte getInstance-Methode zu synchronisieren oder eine Registry für alle Singletons zu erstellen.
Version 1:
public class MySingleton {
private static MySingleton instance = null;
private MySingleton() {}
public static synchronized MySingleton getInstance() {
if(instance == null) {
instance = new MySingleton();
}
return instance;
}
}
Lazy loading, thread safe mit Blocking, geringe Leistung wegen synchronized
.
Version 2:
public class MySingleton {
private MySingleton() {}
private static class MySingletonHolder {
public final static MySingleton instance = new MySingleton();
}
public static MySingleton getInstance() {
return MySingletonHolder.instance;
}
}
Lazy loading, thread safe mit non-blocking, hohe Leistung.
Es gibt vier Möglichkeiten, ein Singleton in Java zu erstellen.
-
Eifrige Initialisierung Singleton
public class Test { private static final Test test = new Test(); private Test() { } public static Test getTest() { return test; } }
-
Lazy initialization singleton (thread safe)
public class Test { private static volatile Test test; private Test() { } public static Test getTest() { if(test == null) { synchronized(Test.class) { if(test == null) { test = new Test(); } } } return test; } }
-
Bill Pugh Singleton mit Halterungsmuster (vorzugsweise das beste)
public class Test { private Test() { } private static class TestHolder { private static final Test test = new Test(); } public static Test getInstance() { return TestHolder.test; } }
-
Enum singleton
public enum MySingleton { INSTANCE; private MySingleton() { System.out.println("Here"); } }