Java Singleton Instanziierung

8

Ich habe drei Möglichkeiten gefunden, einen Singleton zu instantiieren, aber ich habe Zweifel, ob einer von ihnen der beste ist. Ich verwende sie in einer Multi-Thread-Umgebung und bevorzuge faule Instanziierung.
Probe 1:

%Vor%

Beispiel 2:

%Vor%

Beispiel 3:

%Vor%

Das Projekt, in dem ich ATM verwende, verwendet Sample 2 überall, aber ich mag Sample 3 eher. Es gibt auch die Enum-Version, aber ich verstehe es einfach nicht.

Die Frage ist hier - in welchen Fällen sollte / sollte ich keine dieser Varianten verwenden? Ich bin nicht auf der Suche nach langen Erklärungen (es gibt viele andere Themen, aber alle drehen sich irgendwann um IMO), ich würde es gerne mit wenigen Worten verstehen.

    
jurchiks 16.01.2011, 15:35
quelle

4 Antworten

18

Der sicherste und einfachste Weg, ein Singleton in Java zu implementieren, ist die Verwendung von Enums (wie Sie es bereits erwähnt haben):

%Vor%

Die enum-Semantik garantiert, dass es nur ein INSTANCE

gibt

Wenn Sie nicht den Enum-Ansatz verwenden, müssen Sie auf eine ganze Reihe von Aspekten achten, wie Race Conditions und Reflection. Ich habe Singles von einigen Frameworks gebrochen und sie missbraucht, weil sie nicht richtig geschrieben wurden. Das Enum garantiert, dass niemand es bricht.

    
Bozho 16.01.2011, 15:41
quelle
4

Beispiel 1 verwendet keine faule Initialisierung.

Probe 2 und 3 sind beide faul. Beispiel 2 verwendet das Initialization on Demand Holder-Idiom (IODH) mit keinem Synchronisierungsoverhead . Daher ist es schneller als Beispiel 3.

In effektivem Java (Punkt 3) empfiehlt Joshua Bloch, dass ein Enum-Typ mit einem einzelnen Element die beste Methode für die Implementierung eines Singleton ist .

Wenn Sie sich jedoch über den Enum-Typ unsicher sind, halten Sie sich an IODH.

    
dogbane 16.01.2011 15:51
quelle
2

Stellen Sie zuerst absolut sicher, dass Sie ein Singleton benötigen und dass Sie einen "globalen" Zugriff auf das Singleton bereitstellen möchten. Ich habe festgestellt, dass Clients des Singletons in vielen Fällen nicht wissen müssen, dass es ein Singleton ist. Sie müssen nur einen Service erhalten, wenn sie instanziiert werden.

Unabhängig davon, wie Sie das Singleton erhalten (wenn überhaupt), sollten Sie daher überlegen, wie Ihre Klassen Zugriff auf dieses Objekt erhalten. Während dies bedeutet, Konstruktoren zu ändern und "Verteilungsänderungen" zu ändern, habe ich festgestellt, dass Frameworks zur Abhängigkeitsinjektion die Kosten senken. Das DI-Framework kann sich dann auch um Singleton-Instantiierung kümmern (z. B. Guice tut das).

Abgesehen davon. Option 3 ist die typische und am häufigsten verwendete (und threadsichere) Version, mit der ich vertraut bin. Option 1 ist meistens für nicht-faule Initialisierung (nicht immer akzeptabel). Ich habe noch nie 2 gebraucht gesehen.

    
Uri 16.01.2011 15:48
quelle
1

Beispiel 1: Verwenden Sie, wenn Sie einen faulen Singleton nicht benötigen.
Beispiel 2: Niemals benutzen - es wird mit zu vielen Klassen verwirrend. Und eine innere Klasse, nur um eine Variable zu halten, scheint ein bisschen unnötig zu sein. Beispiel 3: Dies ist ein fauler Singleton. Verwenden Sie es, wenn Sie es brauchen.

    
Sibbo 16.01.2011 15:41
quelle

Tags und Links