Verhalten statischer Variablen in einem Java-Servlet

7

Ich entwickle ein Java-Servlet, das beim Ausführen verschiedene Objektmethoden in neuen Threads startet. Diese Threads sollten auf eine Variable zugreifen, die die spezifische Servlet-Instanz beschreibt, z. B. jobId. Aus diesem Grund habe ich die Variable jobId als statisch deklariert. Der Servlet-Konstruktor berechnet diesen Wert für jede Servlet-Instanz (Aufruf). Ich ging umher, wenn das Servlet mehrmals zur gleichen Zeit aufgerufen wird, die statische Variable jobId wird zwischen den Aufrufen geteilt, was bedeutet, dass einige Threads die falsche jobId erhalten oder für jeden Aufruf einmal berechnet werden - also die Threads, die a Das spezifische Servlet, das gestartet wird, verwendet die Job-ID, die für dieses spezifische Servlet berechnet wurde (so wie ich es möchte). Irgendwelche Ideen? Vielen Dank!

    
Che 02.09.2010, 12:01
quelle

4 Antworten

27

Ein Servlet wird nur einmal beim Start von webapp erstellt und unter allen Anfragen geteilt. Statisch oder nicht, jede Klasse / Instanzvariable wird unter allen Anfragen / Sitzungen geteilt. Sie möchten ihnen keine anforderungs- / sitzungsspezifischen Daten zuweisen. Erklären / ordnen Sie sie stattdessen als methodlocal Variable zu. ZB

%Vor%

Es gibt das Vermächtnis und veraltet SingleThreadModel < Eine Schnittstelle, die Sie mit Ihrem Servlet implementieren können, um die Erstellung bei jeder Anfrage zu erzwingen. Aber das ist ein schlechtes Design und unnötig teuer. Deshalb ist es auch veraltet.

Siehe auch:

BalusC 02.09.2010 12:17
quelle
2

static bedeutet, dass jede Instanz auf denselben Wert zugreift.
Jeder Benutzer, der mit dem Servlet verbunden ist, greift auf den gleichen Wert zu. Ihre Job-ID wird wahrscheinlich falsch sein, wenn 2 oder mehr Benutzer miteinander verbunden sind.

Sie müssen für jede Verbindung einen eigenen Wert erhalten und ihn woanders speichern.

Ressourcen:

Zum selben Thema:

Colin Hebert 02.09.2010 12:04
quelle
2

Statische Variablen werden geteilt. Statische Variablen gehören keiner Instanz an und sind für alle Instanzen der Klasse zugänglich. Wenn Sie einen Konstruktor verwenden, der zum Erstellen eines Objekts (einer Instanz der Klasse) verwendet wird, ist das Festlegen einer statischen Variablen in einem Konstruktor in der Regel nicht sinnvoll, da es außerhalb des Bereichs des Objekts liegt, das Sie erstellen .

Was funktionieren würde, könntest du die jobId in die HttpSession legen und dann hätte jeder Benutzer eine eigene Kopie davon.

    
Nathan Hughes 02.09.2010 12:06
quelle
2

Die Instanziierungsrichtlinie für Servlets ist in der Servlet-Spezifikation nicht definiert (so weit ich mich erinnern kann, anywho), aber das übliche Verhalten scheint zu sein, nur eine Instanz pro Servlet-Konfiguration zu erstellen. In diesem Fall würde jede Anfrage dieselbe Variable verwenden.

Wenn ich Sie wäre, würde ich in Erwägung ziehen, die jobId als Parameter an die Runnable s zu senden, mit der Sie die Threads ausführen. Zum Beispiel, statt dessen:

%Vor%

Reflektieren Sie die statischen Variablen wie folgt:

%Vor%

Einfacher zu lesen, keine Nebenläufigkeitsprobleme - reiner Gewinn.

    
gustafc 02.09.2010 12:28
quelle