Singleton?

flashray

Erfahrenes Mitglied
Hallo Freunde,

Ich habe in meiner Applikation mehrere Singletonklassen die sich gegenseitig Aufrufen.

Folgendes ...

Code:
Class Singleton {
   int a = 3;
   int b = 5;
   int c = 7;
   ...
}

Was ist richtig oder effizienter oder besser?

Möglichkeit 1:
Code:
Class SingletonUser {
   int a;
   int b;
   int c;
   
   public SingletonUser
      a = Singleton.getInstance().a;      
      b = Singleton.getInstance().b;
      c = Singleton.getInstance().c;
   }
}


Möglichkeit 2:
Code:
Class SingletonUser {

   Singleton s = Singleton.getInstance();
   int a;
   int b;
   int c;
   
   public SingletonUser
      a = s.a;      
      b = s.b;
      c = s.c;
   }
}

Vg Erdal
 
Die zweite Möglichkeit benötigt, denke ich, mehr Arbeitsspeicher, weil dein Singleton-Objekt während der ganzen Laufzeit des Programms im RAM verweilt.

Die erste Möglichkeit schätze ich dagegen etwas langsamer ein, da stets eine neue Instanz deiner Singleton-Klasse erstellt werden muss.


=> Wenn du also genugt Speicher zur Verfügung hast, verwende die zweite Methode :)

Anmerkung: Nein, ich bin kein Java-Profi. Falls das so nicht stimmt, wäre ich für Fehlerkorrekturen dankbar!
 
Danke Stefan, für die Antwort.

Kann dies jemand bestätigen, ergänzen oder verbessern?

Hinweis: Das Beispiel in meinem ersten Post war nur ein Mini-Mini-Beispiel. Meine Applikation enthält ca. 10 Singleton Klassen in einem Umfang von 200 bis 700 Zeilen je Klasse und insgesamt mehr als Hundert aufrufe von SingletonMethoden und SingletonVariablen. D.h. der Unterschied zwischen Möglichkeit 1. und 2. wäre dann schon erheblich, wenn die Beschreibungen von Stefan stimmen.

Vg Erdal
 
Bei der ersten Variante erzeugt er keineswegs immer ein neues Objekt. Deswegen heisst es ja Singelton (Es kann nur eins geben).

Bei der ersten Variante koennte es sein, das der Garbage Collector das Objekt zerstoert, da es keine Referenz mehr auf das Objekt besteht. Bin mir da aber nicht sicher.
Sollte das Objekt durch irgendeine Referenz bestehen bleiben waer die erste Variante sehr ressourcenlastig, weil das aufrufen von Methoden viel Speicher benoetigt.

Deswegen gibt es in C auch inline :D

Mein Loesungsvorschlag:
Wenn du die Klassen spaeter nicht mehr benoetigst, sondern nur die Attributwerte, dann wuerde ich es in Dateien auslagern. Solltest du jedoch immer wieder auf die Klassen zugreifen waere die 2. Variante besser.
 
Noch eine Frage.
Aus deinem Code Beispiel schliesse ich das die Attribute statisch sind, somit ist das Singleton unnoetigt oder sind in den Klassen noch andere Methoden/Attribute?
 
Hi,

illax hat gesagt.:
Bei der ersten Variante koennte es sein, das der Garbage Collector das Objekt zerstoert, da es keine Referenz mehr auf das Objekt besteht.

Der GC sollte dieses Singleton Object nicht wegräumen wenn flashray das richtige Singleton Pattern angewandt hat. Denn es hat ja selbst eine Referenz von sich.

Code:
private static FooBar INSTANCE;

public static FooBar getInstance() {
    if (INSTANCE == null) {
        INSTANCE = new FooBar();
    }

    return INSTANCE;
}

Gruß

Romsl
 
Hallo und Halli,
Also zunächst denke ich mal ist es gehupft wie gesprungen, vorausgesetzt, dass Singleton.getIntance() tatsächlich und sinnvolelrweise dafür sorgt nur eine Instanz des Objektes rauszugeben, welches dann auch immer und grundsäztlich im Speicher verweilt, soloange man die Referenz, die statisisch sein sollte (sonst hätte man ja auch keine statische getInstance() Methode); gelöscht wird, was bei Singleton-Objekten keinen sonderlichen Sinn hätte.
Der einzige Unterschied zwischen Version 1 und 2 besteht darin, dass SingletonUser auch eine refrenz hält, um halt kein erneutes getInstance() aufzurufen. Also wird lediglich Speicher für die Variable verwendet, ist aber zu vernachlässigen.



illaX hat gesagt.:
Bei der ersten Variante erzeugt er keineswegs immer ein neues Objekt. Deswegen heisst es ja Singelton (Es kann nur eins geben).

Bei der ersten Variante koennte es sein, das der Garbage Collector das Objekt zerstoert, da es keine Referenz mehr auf das Objekt besteht. Bin mir da aber nicht sicher.
Sollte das Objekt durch irgendeine Referenz bestehen bleiben waer die erste Variante sehr ressourcenlastig, weil das aufrufen von Methoden viel Speicher benoetigt.

Deswegen gibt es in C auch inline :D

Mein Loesungsvorschlag:
Wenn du die Klassen spaeter nicht mehr benoetigst, sondern nur die Attributwerte, dann wuerde ich es in Dateien auslagern. Solltest du jedoch immer wieder auf die Klassen zugreifen waere die 2. Variante besser.

Also zunächst mal hat nicht C inline-Funktionen sondern C++ (kleiner aber ich denke doch wichtiger Unterschied) In Java gibt es sowas ähnliches nur halt unter anderem Namen. Final-Methoden sind nicht nur nicht weiter überschreibbar, sondern werden meines Wissens vom Compiler so weit möglich inline behandelt.
Der Garbage Collector wird kein Objekt zerstören, was noch verwendet wird. Da SingletonUser eine Refferenz beinhaltet ist dies also nur dann der Fall, wenn dieser SingletonUser nicht mehr gehalten werden würde, vorausgesetzt, das Singleton ebenfalls nirgenwo anders gehalten werden würde. Da aber die Singleton-refferenz ganz offenbar statisch als Klassenvariable gehalten werden müsste, sonst wäre ja getInstance() nicht statisch, wird also Singleton nicht vom GC erlegt.

BTW dieser Singleton Ansatz kann durchaus sinnvoll sein, so man davon ausgeht, dass Singleton auch noch von anderen Klassen als nur SingletonUser verwendet werden könnte und vermutlich auch soll.

in diesem Sinne

Takidoso
 
Ich schliesse mal aus deinem Text:
1. Das Singleton Objekt wird solange nicht weggeraeumt bis ich dem Attribut instance null zuweise

2. Also ist die zweite Version viel performanter, da ich nur noch eine Referenz speicher und nicht staendig die Methode getInstance() noch zusaetzlich aufrufen muss.


Zu "inline" habe ich noch etwas gefunden:
Java compilers can only inline a method if it is final, private, or static (and Hans Hall has noted that javac will only inline if a method has no local variables). If your code spends lots of time calling a method that has none of these modifiers, consider writing a version that is final.

Also entscheidet der Compiler ob es "inline" ist?
 
ja der Compiler entscheidet schließlich ob es inline ist, mach C++ auch!
das Schlüsselwort inline in C++ bewirkt auch nicht notwenidiger weise eine inline-Funktion, sondern es ist lediglich ein Hinweis des Programmeirers, nach dem motto mach mal wenn du kannst.
Aus früheren C Tagen verwendete man zum Beispiel auch das Schlüsselwort Register, was nur als Hinweis zu verstehen ist, wenn der Compiler grade keines frei hatte wurde dann auch kein Register verwendet.

Die inkrementationsbefehle (i++, ++i, i--, --i ...) hingegen waren ursprünglich der Befehl ein Machienen-Inkrement auszuführen um Zeit zu sparen. Später übernahmen dies die Optimierer von selbst, so dass i = i + 1 tatsächlich den selben Maschinen-Code erzeuge wie i++ und i +=1; War aber soweit ich informiert bin zu Beginn der Sprache C nicht so

(ich hoffe der kleine Exkurs wird mir vergeben)

takidoso
 
Hallo!

Code:
private static FooBar INSTANCE;

public static FooBar getInstance() {
    if (INSTANCE == null) {
        INSTANCE = new FooBar();
    }

    return INSTANCE;
}
Diese Singleton Implementierung kann bei Benutzung in multithreaded Umgebungen nicht sicher funktionieren.

Besser so:
Code:
private static FooBar INSTANCE = new FooBar();

public static FooBar getInstance() {
    return INSTANCE;
}

Gruss Tom
 
Zurück