# Singleton threadsafe



## _Andi91 (31. Jan 2012)

Hi,

steh grad ein bisschen aufn Schlauch...
Wie ich die Initialisierung eines Singletons threadsafe mache ist mir klar. Ich benutze hier entweder ein enum als Singleton oder das Holder Idiom.
Aber um das Singleton und dessen Attribute 100%ig threadsafe zu machen, muss ich die Attribute noch zusätzlich als volatile deklarieren?
Das Singleton Objekt liegt ja dann im statischen Speicherbereich!? Die Frage ist dann im Endeffekt also ob dieser zwischen allen Threads geshared wird, oder ob auch von diesem jeder Thread nur eine Kopie macht?


----------



## maki (31. Jan 2012)

Zeig doch mal den Code...

Holder und Enum sorgen nur dafür, dass das "instance" Attribute Threadsicher ist, volatile hilft nur bei einm einzigen Attribut.
synchronized bzw. explizite Locks sind meist die sicherere Möglichkeit.


----------



## _Andi91 (31. Jan 2012)

Also einfachstes Beispiel mit einem enum Singleton:


```
public enum TestE
{
  INSTANCE;
  
  private String attribute;

  public String getAttribute()
  {
    return attribute;
  }
  public void setAttribute(String attribute)
  {
    this.attribute = attribute;
  }
}
```

Wenn ich nun in einer multithread Umgebung bin und attribute wird durch einen Thread gesetzt, bekommen die anderen Threads diese Änderung mit? Oder müsste hierfür attribute noch volatile deklariert werden?


----------



## maki (31. Jan 2012)

Bei einm einzigen Attribut reicht volitale, bei mehreren nicht.

Allerdings nutzt du das Enum Singleton wie eine globale Variable, darüber solltest du dir imho mehr Gedanken machen.


----------



## _Andi91 (31. Jan 2012)

maki hat gesagt.:


> Bei einm einzigen Attribut reicht volitale, bei mehreren nicht



Wie ist das jetzt genau gemeint? Versteh grad ned was du dami meinst.



maki hat gesagt.:


> Allerdings nutzt du das Enum Singleton wie eine globale Variable, darüber solltest du dir imho mehr Gedanken machen.



Ja schon klar, dass ma des möglichst vermeiden sollte aber manchmal gehts ned anders bzw. machts anders ned viel Sinn.


----------



## maki (31. Jan 2012)

Das meine ich damit:

```
// ACHTUNG: falsch!

public enum TestE
{
  INSTANCE;
  
  private String attribute;

  private String anotherAttribute;
 
  public String getAttribute()
  {
    return attribute;
  }

  public void setAttribute(String attribute)
  {
    this.attribute = attribute;
  }

  public String getAnotherAttribute()
  {
    return anotherAttribute;
  }

  public void setAnotherAttribute(String anotherAttribute)
  {
    this.anotherAttribute = anotherAttribute;
  }

}
```
Das ist *nicht* Threadsafe, hier bräuchte man explizite Locks oder synchronized.


----------



## _Andi91 (31. Jan 2012)

mh also konkret heist das also dann wirklich, dass eine Änderung eines Attributwertes im Singleton evtl. nicht von anderen Threads bemerkt wird?
Wenn es so ist, könnte man dieses Problem ja beheben in dem man alle Attribute im Singleton als volatile deklariert... (oder die setter synchronized)


----------



## maki (31. Jan 2012)

> Wenn es so ist, könnte man dieses Problem ja beheben in dem man alle Attribute im Singleton als volatile deklariert... (oder die setter synchronized)


Wie bereits gesagt, volatile hilft dann nicht mehr.
synchronized dann nicht nur für Setter, sondern auch für getter.

AngelikaLanger.com - Regeln für die Verwendung von volatile - Angelika Langer Training/Consulting


----------



## _Andi91 (31. Jan 2012)

Den Artikel kenne ich.
Wenn ich das richtig verstehe, dann beschreibt folgender Abschnitt im Arktikel genau das, was ich will.



> Mehrfach-Veröffentlichung von Information
> Betrachten wir den Fall, dass Informationen nicht nur einmal zur Verfügung gestellt werden soll, sondern immer wieder neue Information anderen Threads gegenüber veröffentlicht werden soll.  Kann man dafür volatile gebrauchen?  Unter Umständen geht es - und zwar immer dann, wenn sich die veröffentlichte Information selbst nicht verändert, sondern stets durch komplett neue ersetzt wird.
> Hier ist ein Beispiel:
> 
> ...


----------

