2008-11-26 7 views
6

Sind die threadlocals-Variablen global für alle Anforderungen an das Servlet, das die Variablen besitzt?threadlocal-Variablen in einem Servlet

Ich benutze Harz für den Server.

Danke für Awnser.

Ich denke, ich kann mich selbst klarer machen.

Der spezifische Fall:

Ich möchte:

  • eine statische Variable initialisieren, wenn die Anforderung die Ausführung beginnt.
  • Lage sein, den Wert der Variablen in den weiteren Ausführungen von Methoden aus dem Servlet in einer Thread-Sicherheit Art und Weise aufgerufen abzufragen, bis die Anforderung die Ausführung

Antwort

3

endet Ich denke, sich auf alle Anfragen mit, dass aus global nur bestimmter Thread Andere Threads erhalten weitere Kopien der Thread-lokalen Daten. Dies ist der Schlüsselpunkt des threadlokalen Speichers: http://en.wikipedia.org/wiki/Thread-local_storage#Java.

Wenn Sie die entsprechende Option in der Servlets-Konfiguration nicht aktivieren, verwendet der Servlet-Container Ihr Servlet mit mehreren Threads, um Anfragen parallel zu behandeln. So effektiv hätten Sie separate Daten für jeden Thread, der Clients bedient.

Wenn Ihre WebApplication nicht verteilt ist (auf mehreren Java Virtual Machines ausgeführt wird), können Sie das Objekt ServletContext verwenden, um gemeinsam genutzte Daten über Anforderungen und Threads hinweg zu speichern (stellen Sie sicher, dass sie ordnungsgemäß gesperrt werden).

+0

In der Tat. In einem früheren Projekt habe ich das Ticket eines Benutzers in seiner Sitzung gespeichert und einen Filter erstellt, um das Ticket von der Sitzung an einen lokalen Thread zu übertragen, um sicherzustellen, dass der Authentifizierungsstatus des Benutzers immer dem Thread zur Verfügung steht, der die Anfrage bearbeitet. – Julie

0

Threadlocal-Variablen sind immer so definiert, dass global darauf zugegriffen werden kann, da der Punkt darin besteht, Informationen transparent um ein System herumzugeben, auf das überall zugegriffen werden kann. Der Wert der Variablen ist an den Thread gebunden, für den er festgelegt wurde. Daher kann die Variable, obwohl sie global ist, abhängig vom Thread, auf den sie zugreifen, unterschiedliche Werte haben.

Ein einfaches Beispiel wäre die Zuordnung einer Benutzeridentitätszeichenfolge zu einem Thread in einer lokalen Threadvariablen, wenn die Anforderung im Servlet empfangen wird. Überall in der Verarbeitungskette dieser Anforderung (vorausgesetzt, sie befindet sich in demselben Thread in derselben VM) kann die Identität durch Zugriff auf diese globale Variable abgerufen werden. Es wäre auch wichtig, diesen Wert zu entfernen, wenn die Anfrage verarbeitet wird, da der Thread in einen Thread-Pool zurückgelegt wird.

2

Wie Adiel sagt, ist der richtige Weg, dies zu tun wahrscheinlich, den Request-Kontext zu verwenden (d. H. HttpServletRequest), nicht ein ThreadLocal zu erstellen. Es ist zwar möglich, hier einen ThreadLocal zu verwenden, aber Sie müssen darauf achten, Ihren Thread zu bereinigen, da sonst die nächste Anfrage, die den Thread erhält, den Wert sehen wird, der mit der vorherigen Anfrage verknüpft ist. (Wenn die erste Anfrage mit dem Thread erledigt ist, wird der Thread in den Pool zurückkehren und die nächste Anfrage wird ihn sehen.) Kein Grund, solche Dinge zu verwalten, wenn der Anfragekontext für genau diesen Zweck existiert.

+0

Sie könnten auch einen Servlet-Filter verwenden, um den ThreadLocal zu verwalten, zumindest wäre die Erstellung/Bereinigung an einer Stelle. – sehugg

+1

-1 gibt es definitiv einen guten Grund, "so etwas zu managen", gibt es einen Unterschied zwischen dem Argument 1000 Mal um Ihre Anwendung zu führen, im Vergleich zu nur einem statischen Getter ;-) – peenut

+1

Ich verstehe Ihren Kommentar Peenut nicht. Meine Antwort hat nichts damit zu tun, ob ich ein Argument um das 1000-fache oder einen statischen Getter übergebe. Es handelt sich vielmehr um die Wahl zwischen der Verwendung von ThreadLocal-Speicher und HttpServletRequest als Kontext für HTTP-Anforderungen. Vorausgesetzt, dass das OP möchte, dass die Bindungen für die Dauer der Anforderung dauern, ist der richtige Kontext der HSR (Lebenszyklus stimmt mit der Anforderung überein), kein ThreadLocal (gemeinsam für Anforderungen, da Worker-Threads in der Regel zusammengefasst werden). Mit HSR können Sie vermeiden, den Kontext zu bereinigen, da er am Ende der Anforderung verworfen wird. –

4

Kurze Antwort: Ja.
Ein bisschen länger: So macht Spring seine Magie. Siehe RequestContextHolder (über DocJar).

Vorsicht ist jedoch notwendig - Sie müssen wissen, wann das ThreadLocal ungültig wird, wie man es auf andere Threads überträgt und wie man sich (nicht) mit einem nicht threadlokalen Kontext verheddert.

Oder Sie könnten nur Frühling verwenden ...

+0

+1 Antwort auf den Punkt! – peenut

1

Mit Thread Anfrage speichern scoped Informationen das Potenzial zu brechen hat, wenn Sie Servlet 3.0 suspendierbar Anfragen (oder Jetty Fortsetzungen) verwenden diejenigen API mehrere Threads unter Verwendung eines einzigen verarbeiten anfordern.