# Singleton für In-Memory-Caching in WebApp



## HankScorpio (8. Okt 2012)

Hallo,

ich bastele zur Zeit eine kleine Java-Webapplikation. Innerhalb der Applikation habe ich eine relativ große Baum-Datenstruktur. Diese wird recht aufwendig aus den Daten eines RDBMS aufgebaut, wofür viele Querys und auch Dateizugriffe nötig sind. Diese Datenstruktur wird für fast jeden Seitenaufruf der Webapplikation lesend benötigt. Bisher baue ich die Struktur für jeden Request neu auf, was aber ziemlich ineffizient und total überflüssig ist (nur fürs Experimentalstadium akzeptabel). An sich könnte die Struktur aber dauerhaft im Speicher bleiben und müsste nur ab und zu (im Einsatzfall vielleicht alle paar Tage) aktualisiert werden. Hunderte Requests könnten mit den gleichen Daten bedient werden.

Stellt sich die Frage: Wie mache ich das am geschicktesten? Die naheliegenste Lösung war für mich ein Singleton.


```
public final class Singleton {

   private static final Singleton INSTANCE = new Singleton();
 
   private Singleton() {
      // Hier der aufwendige Aufbau der Struktur.
   }

   public static Singleton getInstance() {
      return INSTANCE;
   }

   // ...

}
```

Klar: Es muss verhindert werden, dass gelesen wird, während die Sturktur neu aufgebaut wird (was auch von der WebApp angestoßen werden kann). Da könnte man ja mit einem Lock arbeiten. Aber wie gesagt, der Bearbeiten-Fall ist selten. Die Struktur wird in der Regel nur gelesen.

Meine Frage: Was spricht dagegen, es über ein solches Singleton zu lösen? Welche Probleme habe ich nicht bedacht? Oder kann man das so machen?

Das Singleton müsste ja eigentlich für die gesamte Lebensdauer der "Application" bestehen und auch gleichzeitigen Zugriffen durch mehrere Requests standhalten, wenn sie alle nur lesend darauf arbeiten. Kommt halt auf das Innenleben der Klasse an, das ist klar.

Übrigens: Load-Verteilung auf mehrere Tomcat-Server oder so spielt keine Rolle für das Vorhaben. Das läuft bloß auf einem einzelnen Server, also um die Verteilung der Daten über mehrere Server hinweg etc. müsste man sich hier keine Gedanken machen. 

Es geht mir jetzt zentral um die Frage: Normales Singleton + Java WebApp  =  "Finger weg" (Wieso??) oder "Kann man machen"

Danke schon mal für euren Rat!

Viele Grüße,
Hank Scorpio


---
_"But beware of his generous pensions, plus three weeks paid vacation each year. And on Fridays the lunchroom serves hot dogs and burgers and beer! He loves German beer!"_


----------



## freez (8. Okt 2012)

Also mit static würde ich da gar nicht erst anfangen.

Ich würde ein Managed Bean im Application Scope nehmen. Ist quasi Singleton.


----------



## Sym (9. Okt 2012)

freez hat gesagt.:


> Also mit static würde ich da gar nicht erst anfangen.
> 
> Ich würde ein Managed Bean im Application Scope nehmen. Ist quasi Singleton.


Das ist nicht nur quasi ein Singleton. 

Diese Lösung ist zu bevorzugen. Singletons sind nicht immer einfach: Singleton Pattern in Java


----------



## HankScorpio (9. Okt 2012)

Danke euch für den Verweis auf die Managed Bean! 



freez hat gesagt.:


> Also mit static würde ich da gar nicht erst anfangen.





Sym hat gesagt.:


> Singletons sind nicht immer einfach



Aber damit ich das noch etwas besser verstehe: Wo liegt das Problem beim "klassischen" Singleton im Zusammenhang einer Webapplikation, weshalb ihr davon eher abraten würdet? Oder ist das eher eine Frage von Stil und Geschmack? Oder ist es aus vorausschauenden Gründen nicht gut, weil es in einer Cluster-Umgebung vllt. Probleme macht? ...? 



Sym hat gesagt.:


> Singletons sind nicht immer einfach: Singleton Pattern in Java


Denn der Singleton-Code, den ich ganz oben im Posting habe, ist ja sogar schon der "gute", den der verlinkte "TheServerSide"-Artikel am Ende als Lösung für Performance- und Thread-Sicherheitsprobleme herleitet. :-?


----------



## Sym (9. Okt 2012)

Ja, Dein Code ist genau richtig für nen Singleton.

Ein Problem mit Singletons allgemein, ist die Testbarkeit. Die meisten Frameworks können ein Singleton nicht mocken. Gerade mit den vielen neuen DI-Frameworks gibt es eine Hülle an Möglichkeiten, die auch Tests unterstützen.

Im Grunde würde ich sagen, Singletons sind einfach 1990...

edit: ein Beispiel ist mir noch eingefallen: Bei einem Singleton wird die Instanz (sofern man ein Singleton richtig nutzt) beim Starten der JVM erzeugt. Der von mir verlinkte Beitrag zeigt ja, wann (und warum) man eine Lazy-Instanziierung vermeiden sollte.

Nutzt Du hingegen eine ApplicationScoped-Bean liegt die Instanziierung beim Container. Und der sollte wissen, wann der geeignete Zeitpunkt ist.

Ach Singletons sind einfach nur 1990


----------

