synchronized bei Servlets

  • Themenstarter Themenstarter Guest
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Ich hab ein kleines Problem mit Servlets. Es existiert zur Laufzeit ja in der Regel nur ein Servlet-Objekt. Dies kann dann ja zu Konflikten führen wenn 2 gleichzeitig auf das Servlet zugreifen. Momentan habe ich das so gelöst, dass doGet und doPost als synchronized definiert sind.
Die Frage ist, jetzt ob das so ok ist oder ob ich das synchronized vielleicht doch gezielter einsetzen sollte um einzelne Objekte zu schützen. Wie macht ihr das immer?
 
meiner Philosophie nach sollte ein Servlet keine Exemplarvariablen/ Klassenattribute enthalten,
sondern nur mit der Session und eigenen Objekten/ Parametern arbeiten,
HTTPRequest/ Response kommen ja auch als Parameter,

in diesem Fall ist kein synchronized nötig, parallele Ausführungen stören sich nicht,

wenn man doch lieber mit Zuständen arbeitet gibt es meines Wissens nach eine Server-Einstellung, dass pro Request ein neues Servlet-Objekt erstellt wird,
sind ja erstmal nur billige 4 Bytes,
vielleicht ist das auch Standard,
ich würde mich allerdings in beide Richtungen nicht auf solche externen Konfigurationen verlassen,
genausogut kann man in doGet ein neues Zustandsobjekt erschaffen oder ein vorhandenes laden
 
doGet und doPost sollten keinesfalls auf synchronized gesetzt werden, da das die Performance bei vielen Usern vorraussichtlich extrem negativ beeinflusst. Es besteht im übrigen auch wenig Sinn darin, diese Methoden zu synchronisieren. Vielmehr musst Du etwaige Klassenvariablen im Servlet Thread-sicher machen. Entweder verzichtest Du ganz darauf (siehe Slater) oder Du machst alle Klassenvariablen thread-local, die noch nicht thread-sicher sind:

http://java.sun.com/javase/6/docs/api/java/lang/ThreadLocal.html
 
Theroetisch könnte ich das so machen. Dann hätte ich allerdings ein kleines Problem. Ich erzeuge in diesem Servlet eine Navigation und diese wird aus einer XML-Datei gelesen.
Um die Laufzeit zu verbessern ist dieses XML-Dokument als DOM in einer meiner Datenklassen hinterlegt.
Diese Datenklasse halte ich in einem Contoller der dann die passenden Daten auf Anfrage des Sevlets bereitstellt.
Dazu brauche ich eine Exemplarvariable da ich sonst das XML-Dokument jedes mal neu einlesen muss.
 
@byto: Das sieht doch schon ganz vielversprechend aus. Hast du vielleicht ein kleines Beispiel wie das genau funktioniert? Die Doku von Sun ist da doch schon etwas mager.
 
also ApplicationScope, SessionScope usw. gibt doch wohl J2EE an sich vor,
ich denke da an den ServletContext
http://java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpSession.html#getServletContext()

und dass es um J2EE geht, davon kann man wohl ausgehen 😉
 
Da fällt mir doch was ein. Was wäre wenn ich dem ServletContext mein Document-Objekt als Attribut übergeben würde? Wäre es dadurch threadsicher?
 
Ja, aber ApplicationScope heisst es explizit in JSF. Im übrigen muss man auch beim ServletContext vorsichtig sein, weil die Objekte nicht zwischen verschiedenen JVM-Instanzen propagiert werden. Es ist also von der Konfiguration des Servlet-Containers abhängig. Auch ThreadLocal bietet dafür keine Lösung.
 
Also auf die Konfiguration des Servlet-Containers kann ich mich im Moment nicht verlassen. Momentan zur Entwicklung benutze als Application Server Tomcat. Was aber letztendlich eingesetzt wird steht noch nicht 100%ig fest. Zuletzt war soweit ich weiß WebSphere im Gespräch. Aber sicher ist das noch lange nicht.
 
Naja nur die XML-Datei wird einmal eingelesen. Aus diesem Document-Objekt wird dann immer per XPath ausgelesen wie die Navigation dann aufgebaut werden muss. Theoretisch wäre es also möglich, dass 2 oder mehr gleichzeitig darauf zugreifen und dann müsste es doch eigentlich zu Problemen kommen oder liege ich da falsch?
 
Du liegst falsch.
Wenn 2 Leute gleichzeitig dieselbe Stelle in einem Buch lesen, gibt es dann Probleme?
Nein.
Solange also nur gelesen wird ist also alles in Ordnung.
Probleme gibt es dann, wenn du pro Benutzer einen Zustand in diesem Objekt speichern möchtest.

ms
 
ms hat gesagt.:
Und den ServletContext sollte es in jedem Servletcontainer bzw. Applicationserver geben.
Natürlich. ServletContext ist Teil der Spezifikation. Aber die Implementierung unterscheidet sich teilweise je nach Container.

Fakt ist aber, dass der ServletContext auf die JVM begrenzt ist. Das steht auch so in der Spezifikation:

There is one context per "web application" per Java Virtual Machine.
...
In the case of a web application marked "distributed" in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won't be truly global). Use an external resource like a database instead.
Du musst Dir also im Klaren darüber sein, wie die Anwendung am Ende deployed wird, bevor Du den ServletContext verwendest. Wenn Du z.B. Load Balancing nutzt (z.B. durch einen zentralen Apache Webserver, der die Anfragen auf mehrere Tomcats verteilt), dann fliegst Du mit ServletContext u.U. auf die Nase.
 
byto hat gesagt.:
Fakt ist aber, dass der ServletContext auf die JVM begrenzt ist.
Ich versteh nicht ganz.
Worauf willst du hinaus?
Sprichst du von der Möglichkeit einen Cluster aufzubauen und Daten zu replizieren?

ms
 
Auch wenn das häufig der Fall ist, muss ein Servlet-Container nicht zwangsläufig immer in ein- und derselben JVM-Instanz laufen.
 
Das versuche ich doch die ganze Zeit zu sagen: 😉
Das Scope des ServletContexts ist die JVM-Instanz. Wird ein Objekt im ServletContext gesetzt, so ist dieses Objekt im ServletContext einer anderen JVM-Instanz nicht verfügbar.
 
Doch das macht einen enormen Unterschied. Das würde dann gleichzeitig bedeuten, dass nicht nur ein ServletContext sondern vielleicht 2 oder 3 parallel existieren und wenn ich die Daten im 1. speichern sollte sind diese im 2. und im 3. natürlich nicht vorhanden.
 
byto hat gesagt.:
Das versuche ich doch die ganze Zeit zu sagen: 😉
Das Scope des ServletContexts ist die JVM-Instanz. Wird ein Objekt im ServletContext gesetzt, so ist dieses Objekt im ServletContext einer anderen JVM-Instanz nicht verfügbar.
Wenn er ein Menü hat, welches er beim Starten (egal auf welcher und bei wievielen Instanzen) in der init-Methode des Servlets aufbaut, dann braucht nichts repliziert zu werden und ist trotzdem in jeder Instanz verfügbar. Bin davon ausgegangen, dass er es so implementiert.

Gast hat gesagt.:
Doch das macht einen enormen Unterschied. Das würde dann gleichzeitig bedeuten, dass nicht nur ein ServletContext sondern vielleicht 2 oder 3 parallel existieren und wenn ich die Daten im 1. speichern sollte sind diese im 2. und im 3. natürlich nicht vorhanden.
Wieviele ServletContexte hast du denn bzw. wirst du denn haben?


@byto: Kennst du den schon?
A: Guten Tag, ich heisse Müller ... Müller ohne "K"
B: Müller ohne "K"???
A: Ja, Müller ohne "K".
B: Aber Müller schreibt man doch immer ohne "K"
A: Das sage ich doch die ganze Zeit!!!
🙂


ms
 
Das steht ja leider noch nicht fest. Vielleicht hab ich einen aber vielleicht auch mehrere.
Wie das am Ende aussehen soll wurde noch nicht definiert.

Ich arbeite momentan ja auch nicht an der Version die ausgeliefert werden soll sondern an einem Prototypen.
 
OK hab heute nochmal mit meinem Chef gesprochen. Sieht wohl momentan so aus als obj ich nur einen ServletContext haben werde.

Ist zwar noch nicht 100%ig sicher aber momentan gibt es keine anderen Pläne.
Ich werde es dann einfach mal so probieren und falls ich noch Probleme bekommen sollte melde ich mich nochmal.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben