2012-12-05 12 views
9

Ich habe 2 Möglichkeiten:Singleton und öffentliche statische Variable Java

  1. Singleton Pattern

    class Singleton{ 
        private static Singleton singleton = null; 
    
        public static synchronized Singleton getInstance(){ 
         if(singleton == null){ 
          singleton = new Singleton(); 
         } 
         return singleton; 
        } 
    } 
    
  2. mit einem static final Feld

    private static final Singleton singleton = new Singleton(); 
    
    public static Singleton getSingleton() { 
        return singleton; 
    } 
    

Was ist der Unterschied? (singlethreaded oder Multithread)

Updates: Ich kenne Bill Pugh oder enum Methode. Ich bin nicht auf der Suche nach dem richtigen Weg, aber ich habe nur 1 verwendet. Gibt es wirklich einen Unterschied s/w 1 oder 2?

+0

Nach Ihrer aktualisierten Frage kein Unterschied. –

+1

Diese Frage hat nichts mit Singleton zu tun. Sie fragen nach dem Zugriff auf ein statisches Feld aus dem synchronisierten/nicht synchronisierten Kontext. Tags bearbeiten – Juvanis

+0

@BhavikAmbani Ich stimme nicht zu, da die erste Option jeden Thread sperren wird, der versucht, die Instanz zu bekommen, und daher etwas weniger performant ist. –

Antwort

10

Der Hauptunterschied besteht darin, dass bei der ersten Option der Singleton nur initialisiert wird, wenn getInstance aufgerufen wird, während er bei der zweiten Option initialisiert wird, sobald die enthaltende Klasse geladen wird.

Eine dritte (bevorzugt) Option, die träge ist und Faden sicher ist, eine ENUM zu verwenden:

public enum Singleton { 
    INSTANCE; 
} 
+0

Mein Fehler, irgendwie verpasst es. Habe die Frage jetzt aktualisiert. Ich bin mir auch der ENUM Singleton Instanz bewusst, wollte nur den Unterschied b.w the 2 wissen, aber trotzdem danke! – Achow

2

Es gibt einen Unterschied:

Lösung 1 ist eine verzögerte Initialisierung, die Singleton-Instanz sein wird, auf der ersten Geltendmachung von getInstance erstellt

Lösung ist 2 eine eifrige Initialisierung wird die Singleton-Instanz erstellen, wenn die Klasse Loades

Sie beide sind threadsicher, rufen die zweite Multi-Thread ist ein wenig irreführend

+1

Nun, ich habe nicht in das Multi-Threaded-Bit.Es wurde bearbeitet ..: P – Achow

1

Also, mit dem Update beide oben genannten Optionen sind Thread-sicher. Die Option synchronized erfordert jedoch, dass jeder Thread, der instance aufruft, diese Sperre annimmt, wodurch die Leistung verringert wird, wenn dies sehr häufig geschieht. Auch die Verwendung von synchronized auf der Methodenebene hat das potentielle Problem, eine öffentlich verfügbare Sperre (die Klasse selbst) zu verwenden, die daher, wenn ein Thread diese Sperre erwirbt (was er könnte), zu einem Deadlock führen könnte. Die Option static final ist leistungsfähiger, führt jedoch keine verzögerte Initialisierung des Singleton durch (was je nach System möglicherweise kein Problem darstellt).

weitere Option, die threadsicher lazy init des Singleton erlaubt, ist wie folgt:

public class MySingleton{ 
     private static class Builder{ 
      private static final MySingleton instance = new MySingleton(); 
     } 

     public static MySingleton instance(){ 
      return Builder.intance; 
     } 
} 

Dies funktioniert, weil die statische innere Klasse initialisiert werden, wird guarenteed bevor eine Methode in der Klasse enthält, ausgeführt wird.

+0

-1 Wähler, kümmern sich um Schlussfolgerung zu klären? –

+0

Ich lese gerade die Antwort, und es hat nicht das Problem, das ich dachte, es hatte. Entschuldigen Sie. :) Entfernte meine -1. Die Antwort sieht für mich allerdings ein bisschen wie ein Wortsalat aus ... und berührt nur den wahren Unterschied (faule oder eifrige Initialisierung). Sie erwähnen Leistung und Sperren, aber das ist nicht der Hauptunterschied. – cHao

-1

Singleton-Implementierung in Java (wenn Sie das wirklich wollen) kann auf eine elegantere Weise durchgeführt werden, als Sie für eifrige und faule Initialisierung beschrieben haben. Überprüfen Sie the enum way beschrieben von Joshua Bloch und the SingletonHolder solution vorgeschlagen von Bill Pugh jeweils.

Der Wikipedia-Artikel ist auch ein guter Anfang für das Verständnis des Musters und beantwortet Ihre Frage.

+1

Beantwortet die Frage nicht. Wenn Sie einen besseren Weg vorschlagen möchten, ist das in Ordnung ... aber beantworten Sie zumindest die Frage, die Sie dabei stellen. – cHao

+0

Yeah, du hast Recht ... –

2

Die erste Lösung scheint fauler zu sein, aber eigentlich nicht.

Eine Klasse wird initialisiert, wenn zum ersten Mal auf eine statische Methode/ein statisches Feld zugegriffen wird.

Es ist wahrscheinlich, dass getInstance() die einzige öffentlich zugängliche statische Methode/Feld der Klasse ist. Das ist der Sinn des Singletons.

Dann wird die Klasse initialisiert, wenn jemand zum ersten Mal getInstance() aufruft. Das bedeutet, dass die beiden Lösungen in Faulheit im Wesentlichen gleich sind.

Natürlich sieht die zweite Lösung besser aus und funktioniert besser.

+0

Faule Wesen, keine Instanz von Singleton wird erstellt, bis getInstance() explizit aufgerufen wird. Die Klasse wird natürlich beide Male geladen. Oder fehlt mir etwas? – Achow

+1

in der 2. Lösung wird die Instanz nur erstellt, wenn die Klasse initialisiert wird; Die Klasse wird nur initialisiert, wenn auf eine statische Methode/Feld zugegriffen wird, d. h. wenn getInstance() aufgerufen wird. – irreputable

Verwandte Themen