# Servlets richtig verstehen



## Dandro (30. Okt 2007)

Hallo 

Ich bin gerade dabei mich in das Thema Webentwicklung mit Servlets einzuarbeiten.
Bevor ich jetzt lustig drauflosprogrammiere, würde ich gerne ein paar Sachen Fragen.

Ich hab schon ein wenig hier im Forum gesucht und habe erfahren dass mehrere Threads
auf eine Servlet Instanz zugreifen, sprich man sollte die Klasse zumindest so programmieren
dass Instanzvariablen, also "shared Resources" vermieden werden, bzw. wenn, dann so
entwickeln, dass es "sicher" ist.

Nun stellt sich mir aber die Frage inwiefern bspw. das Singleton-Pattern anwendbar ist.
Ich würde gerne ein eigenes HTTPSession Objekt schreiben, das von der HTTPSession
erbt. Das würde ich gern so schreiben, dass es dem Singleton-Pattern entspricht ... falls möglich?

Würde das nicht dann irgendwie dem Single-Thread-Model entsprechen? Wenn das Singleton
Thread-Safe wäre, dann müssten doch alle anderen Threads die aufs Servlet zugreifen darauf
warten, dass der aktuelle Thread mit dem Singleton fertig ist? ^^


Ist bestimm sehr wirr geschrieben, ich verbessere bei Nachfrage gerne XD


----------



## maki (30. Okt 2007)

> Nun stellt sich mir aber die Frage inwiefern bspw. das Singleton-Pattern anwendbar ist.
> Ich würde gerne ein eigenes HTTPSession Objekt schreiben, das von der HTTPSession
> erbt. Das würde ich gern so schreiben, dass es dem Singleton-Pattern entspricht ... falls möglich?


Ähhmm.. das Singleton Pattern wird verwendet, wenn es nur eine einziges Objekt einer Klasse geben soll.
Das passt ja gar nicht zur HTTPSession, oder 



> Würde das nicht dann irgendwie dem Single-Thread-Model entsprechen?


Nein. 
Das STM macht ein Servlet/Webanwendung nicht wirklich Threadsicher dafür aber langsam, daher sollte es nicht verwendet werden.


----------



## Dandro (30. Okt 2007)

maki hat gesagt.:
			
		

> > Nun stellt sich mir aber die Frage inwiefern bspw. das Singleton-Pattern anwendbar ist.
> > Ich würde gerne ein eigenes HTTPSession Objekt schreiben, das von der HTTPSession
> > erbt. Das würde ich gern so schreiben, dass es dem Singleton-Pattern entspricht ... falls möglich?
> 
> ...



Wieso passt das nicht zur HTTPSession? Ich initialisiere die Session doch nur genau einmal pro Anfrage?



			
				maki hat gesagt.:
			
		

> > Würde das nicht dann irgendwie dem Single-Thread-Model entsprechen?
> 
> 
> Nein.
> Das STM macht ein Servlet/Webanwendung nicht wirklich Threadsicher dafür aber langsam, daher sollte es nicht verwendet werden.



Genau das meinte ich doch, wenn man ein Singleton-Pattern innerhalb eines Servlets benutzt, wird es langsamer,
da soetwas doch Ähnlichkeiten mit dem STM hätte, oder?


----------



## maki (30. Okt 2007)

> Wieso passt das nicht zur HTTPSession? Ich initialisiere die Session doch nur genau einmal pro Anfrage?


Überleg doch mal:
Brauchst du mehr als ein einziges Session Objekt?
Abgesehen davon wird eine Session nicht pro ANfrage initialisiert, sondern eben pro Session..



> Genau das meinte ich doch, wenn man ein Singleton-Pattern innerhalb eines Servlets benutzt, wird es langsamer,
> da soetwas doch Ähnlichkeiten mit dem STM hätte, oder?


Nein, was du meintest wäre etwas anderes... etwas, das nicht funktionieren würde.

Vergiss erstmal das Singleton Pattern


----------



## Dandro (30. Okt 2007)

Meiner Auffassung nach müsste ich nur ein HTTPSession Objekt instanzieren, das würde ich am Anfang des Requests machen, also ziemlich früh in den doGet/doPost Methoden. Mit der Instanz kann ich dann meiner Meinung nach weiter-
arbeiten (Werte in die Session sicher etc. damit selbige über mehrere Seitenaufrufe erhalten bleiben)

Ich habe gesagt, dass ich neu in dem Thema bin ... XD

EDIT: wahrscheinlich ist meine auffassung falsch, abr warum?


----------



## HLX (30. Okt 2007)

Eine Session besteht zwischen dem Server und einem Client. Da mehrere Clients auf deinen Server zugreifen dürften, können auch mehrere Sessions gleichzeitig vorhanden sein. Du hast dann mehrere Session-Objekte in deiner VM und das geht mit einem Singleton nicht.


----------



## Dandro (30. Okt 2007)

Genau diese Antwort wollte ich haben  Kann sein, dass es indirekt schon mit einer der vorhergehenden Antworten geklärt war, allerdings war es WENN dann für mich nicht ersichtlich ... Trotzdem erstmal dankeschön an alle, die sich beteiligt haben XD


----------



## Guest (2. Nov 2007)

Nachdem ich nun fleißg gelernt habe (hoffe ich mal) wollte ich mal eure Meinung zu etwas hören.
Auch unabhängig von Sessions nun. Würde ein Singleton-Entwurf mit der Hilfe von ThreadLocal Objekten
funktionieren? So würde doch jeder Thread quasi eine Instanz von dem Singleton besitzen, sehe ich das richtig?


----------



## Dandro (2. Nov 2007)

grml, das war ich gerade


----------



## nebulo (2. Nov 2007)

Von einer Singleton Klasse gibt es *nur eine * Instanz! Lies mal 

http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)


----------



## Dandro (2. Nov 2007)

Jaha, das ist mir bewusst. Wenn man das Pattern

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ThreadLocal.html

damit modifiziert, sollte eigentlich eine Art Threadbezogenes Singleton rauskommen?


----------



## nebulo (2. Nov 2007)

Ich verstehe beim besten Willen nicht, was das Alles mit Singleton zu tun haben soll!

Was ist den dein Problem oder was willst du machen?


----------



## Dandro (2. Nov 2007)

Man nehme das Grundkonzept eines Singletons, undzwar nur eine Instanz insgesamt. Und erweitere es mit dem ThreadLocal-Objekt, und man würde ein abgewandeltes Singleton-Pattern bekommen, undzwar ein solches was nicht INSGESAMT eine Instanz bietet, sondern eines was für jeden laufenden THREAD der darauf zugreift eine Instanz bietet.

Das vermute ich in der Theorie ... was ich wissen will ist, ob meine Theorie soweit stimmt. Praktisch wie ich finde, da es vom Servlet faktisch nur eine Instanz gibt auf die mehrere Threads zugreifen. (Es sei den man benutzt das STM)


----------



## nebulo (2. Nov 2007)

Das hat doch überhaupt nichts mit Singleton zu tun! ThreadLocal ermöglicht es soweit ich das verstehe lediglich Variablen anzulegen die ich nenne es mal "thread private" sind.

Das Singleton-Pattern macht in Zusammenhang mit Thread einfach überhaupt keinen Sinn. Den Threads sind schon vom Prinzip her ein Konzept bei dem mehrere Instanzen nebeneinander existieren können. Das Singleton-Pattern sorgt dagegen dafür das nur eine einzige Instanz erzeugt werden kann. 

Vielleicht verstehe ich noch immer nicht genau was du sagen willst. Aber versuch Dich doch bitte mal nicht so sehr auf irgendein Konzept zu versteifen und sag was du machen willst...


----------



## Dandro (3. Nov 2007)

Es geht mir gerade nicht um einen genaueren Zweck, sondern einfach nur ums Prinzip ^^


```
public class ThreadSingleton {
	
	private static final ThreadLocal<ThreadSingleton> mThreadLocalInstance = new ThreadLocal<ThreadSingleton>();
	
	private ThreadSingleton()
	{
	}
	
	public static ThreadSingleton getInstance()
	{
		ThreadSingleton lThreadSingleton = mThreadLocalInstance.get();
		
		if (lThreadSingleton == null)
		{
			lThreadSingleton = new ThreadSingleton();
			mThreadLocalInstance.set(lThreadSingleton);
		}
		
		return lThreadSingleton;
	}
}
```

Ich sehe das so, dass wenn jetzt unterschiedliche Threads auf getInstance() zugreifen verschiedene Instanzen zurückgegeben werden. Ruft man getInstance() aber mehrmals im gleichen Thread auf, kommt immer wieder die gleiche Instanz zurück. Sooooo sehe ich das? ^^ Es geht mir darum, ob das auch in der Praxis so funktionieren würde.


----------



## nebulo (3. Nov 2007)

Ich glaube jetzt habe ich verstanden worauf du hinaus willst  . Ich denke nicht, dass es so funktionieren wird. Aber sicher bin ich mir nicht! Warum probierst du es nicht einfach mal aus?

Ich würde eine Art Factory bauen. Die eine Hashtable enthält und in der für jeden Thread eben eine Instanz abgelegt wird. Wenn zu dem Thread noch kein Eintrag in der Hashtable ist wird eine Instanz kreiert und dann in der Hashtable abgelegt.


----------



## Dandro (3. Nov 2007)

Gut, ich hab es jetzt mit mehreren Computern mit jeweils mehreren Threads getestet. 
Es funktioniert! Jeder Thread erhält ein eigene Instanz. So wie es sein sollte.

An die Möglichkeit mit der Hashtable habe ich zuerst auch gedacht, nur dann bin ich eben zufällig über dieses "ThreadLocal" gestolpert. Ich denke das ist ein vernünftige Alternative, oder?


----------



## nebulo (3. Nov 2007)

Tendenziell  wäre eine Lösung in der Art wie ich sie beschrieben habe etwas leichter zu verstehen. Aber wenn du deine gut kommentierst spricht denke ich nichts dagegen. Wobei ich natürlich zur Performance deiner  Lösung recht wenig sagen kann, weil ich mich mit dem ThreadLocal nicht genauer auseinandergesetzt habe.


----------



## HLX (3. Nov 2007)

Was soll das bringen, für jeden Thread eine Variable anzulegen? Um einen globalen Effekt zu erreichen müsstest du die Instanzen miteinander synchronisieren, sprich bei Veränderung eines ThreadLocal- Objekts müssen alle anderen Threadlocal-Objekte darüber informiert werden - sofern die Veränderung global für alle gelten soll.

Non-globale Information gehören an die Benutzer-Session. Threads haben im Web-Container keinen Bezug zum Benutzer.


----------



## Dandro (3. Nov 2007)

> Um einen globalen Effekt zu erreichen müsstest du die Instanzen miteinander synchronisieren, sprich bei Veränderung eines ThreadLocal- Objekts müssen alle anderen Threadlocal-Objekte darüber informiert werden - sofern die Veränderung global für alle gelten soll.



Es soll jeweils nur Threadglobal sein, also erfüllt es so gesehen seinen Zweck.



> Non-globale Information gehören an die Benutzer-Session. Threads haben im Web-Container keinen Bezug zum Benutzer.



Ich hab nicht sehr viel Erfahrung mit Servlets. Das war mein Ansatz es zu lösen, da ich dachte (bzw. gelesen habe) dass für jede Anfrage (also jeden "Benutzer") ein Thread erstellt wird. Kannst du mir ein Beispiel geben, wie man soetwas an die Benutzer-Session bindet?


----------



## maki (4. Nov 2007)

imho solltest du dir ein Buch über Servlets (und am besten über Java , siehe Code Conventions) zulegen.
Sowas lernt man nicht "nebenbei", vor allem wenn man vorhat Servlets richtig zu verstehen.


----------



## HLX (4. Nov 2007)

Dandro hat gesagt.:
			
		

> Ich hab nicht sehr viel Erfahrung mit Servlets. Das war mein Ansatz es zu lösen, da ich dachte (bzw. gelesen habe) dass für jede Anfrage (also jeden "Benutzer") ein Thread erstellt wird.


Nein. Das wäre völliger Wahnsinn. Stell dir einen Server mit 2.000 Zugriffen in 10 Minuten vor. Die Zugriffe dauern i.d.R. nur wenige Sekunden, die Sessions sind jedoch mehrere Minuten gültig. Dann müssten 2.000 Threads in der JVM betrieben werden.

Der Tomcat z.B. bedient sich aus einem Threadpool. Wenn ein Request abgehandelt ist, steht der dazugehörige Thread wieder im Pool bereit.



			
				Dandro hat gesagt.:
			
		

> Kannst du mir ein Beispiel geben, wie man soetwas an die Benutzer-Session bindet?



Im Servlet kannst ein Objekt mit

```
request.getSession().setAttribute("Name",Objekt);
```
an der Session ablegen. Das Objekt wird dann unter diesem Namen an der Session im Webcontainer hinterlegt, bis die Session ungültig wird.


----------



## Dandro (4. Nov 2007)

Ok, das ändert das ganze natürlich dann ein wenig XD

Aber ein Thread bearbeitet doch eigentlich immer nur eine Anfrage zur Zeit oder? Würde doch gar nicht gehen, z.B. zwei Anfragen zur selben Zeit bearbeiten? Wenn ich das also richtig sehe, können zwar 2000 Anfragen zur Zeit eingehen, aber immer nur soviel zugleich bearbeitet werden, wie der Threadpool Threads hergibt?


----------



## HLX (4. Nov 2007)

Korrekt.  :toll:


----------

