java singleton Instanziierung
Habe ich festgestellt, drei Arten der Instanziierung ein Singleton, aber ich habe Zweifel, ob eine von Ihnen ist die beste, die es gibt. Ich bin mit Ihnen in einer multi-threaded Umgebung, und lieber faul Instanziierung.
Beispiel 1:
private static final ClassName INSTANCE = new ClassName();
public static ClassName getInstance() {
return INSTANCE;
}
Beispiel 2:
private static class SingletonHolder {
public static final ClassName INSTANCE = new ClassName();
}
public static ClassName getInstance() {
return SingletonHolder.INSTANCE;
}
Beispiel 3:
private static ClassName INSTANCE;
public static synchronized ClassName getInstance()
{
if (INSTANCE == null)
INSTANCE = new ClassName();
return INSTANCE;
}
Dem Projekt bin ich über ATM verwendet, Probe 2 überall, aber ich mag die Art von Probe 3 mehr. Es gibt auch die Enum-version, aber ich verstehe es einfach nicht.
Hier die Frage ist - in welchen Fällen sollte ich/sollten keine dieser Varianten? Ich bin nicht auf der Suche für die langen Erklärungen aber (es gibt viele andere Themen darüber, aber Sie alle schließlich in streiten, IMO), ich möchte es verständlich sein, mit wenigen Worten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die sichere und einfache Möglichkeit zur Implementierung eines singleton in java ist durch die Verwendung von Enumerationen (wie du Sie erwähnt hast):
Enum-Semantik garantiert, dass es nur eine
INSTANCE
Wenn nicht die enum-Ansatz, müssen Sie kümmern sich um ganz viele Aspekte, wie race-conditions und Reflexion. Ich habe breaking singletons einige frameworks und missbrauchen Sie, weil Sie nicht korrekt geschrieben. Die enum garantiert niemand wird ihn brechen.
ClassName.INSTANCE.doSomething(foo)
ClassName.INSTANCE.methodName()
Verwendung des singleton-Methoden (oder vielleicht verwenden Sie statische Importe, um loszuwerden, dasClassName.INSTANCE.
) Teil.enum
Ansatz ist definitiv nicht faul.synchronized
Beispiel 1 verwendet nicht die lazy-Initialisierung.
Probe 2 und 3 sind beide faul. Beispiel 2 nutzt die Initialization on demand holder idiom (IODH) die keine synchronisation-overhead. Daher ist es schneller als Probe 3.
Effektive Java (Item 3), Joshua Bloch empfiehlt, dass ein single-element enum-Typ ist der beste Weg zur Implementierung eines singleton.
Allerdings, wenn Sie unsicher sind über die enum-Typ, stick mit IODH.
Zunächst stellen Sie unbedingt sicher, dass Sie benötigen ein singleton, und dass Sie möchten, um als "global-level" - Zugriff auf den singleton. Ich habe festgestellt, dass in vielen Fällen Kunden des singleton haben keine Notwendigkeit, zu wissen, dass es ist ein singleton. Vielmehr werden Sie nur brauchen, um einen Dienst zu erhalten, wenn Sie instanziiert sind.
So, unabhängig davon, wie Sie erhalten die singleton (wenn überhaupt), überlegen Sie die Möglichkeit, Ihre Klassen Zugriff auf dieses Objekt. Während dies bedeutet ändern von Konstruktoren und ändern "Verteilung der änderungen", ich habe festgestellt, dass dependency injection-frameworks senken die Kosten. Das DI-framework kann auch dann kümmern singleton Instanziierung (z.B. Guice tut).
Abgesehen davon, dass. option 3 ist die typische und häufigste (und thread-sichere) version, die ich bin vertraut mit. Option 1 ist vor allem für non-lazy-Initialisierung (nicht immer zulässig). Ich habe noch nie gesehen, 2 verwendet.
Beispiel 1: Verwenden Sie, wenn Sie nicht brauchen einen faulen Singleton.
Beispiel 2: verwenden Sie Niemals - es wird verwirrend, mit zu viel Unterricht. Und eine innere Klasse nur zu halten, eine variable scheint ein bisschen unnötig.
Beispiel 3: Dies ist ein fauler Singleton. Verwenden Sie es, wenn Sie es brauchen.