2008-11-26 6 views
6

Les variables threadlocals sont-elles globales pour toutes les requêtes effectuées sur la servlet propriétaire des variables? J'utilise de la résine pour le serveur.variables threadlocales dans une servlet

Merci pour cette question.

Je pense que je peux me rendre plus clair.

Cas particulier:

Je veux:

  • initialiser une variable statique lorsque la demande commence l'exécution.
  • pouvoir interroger la valeur de la variable dans les autres exécutions de méthodes appelées à partir du servlet d'une manière de sécurité de fil jusqu'à ce que la demande se termine l'exécution

Répondre

3

Je pense qu'ils sont globaux à toutes les demandes faites avec cette thread spécifique seulement. D'autres threads obtiennent d'autres copies des données thread-local. C'est le point clé du stockage local de thread: http://en.wikipedia.org/wiki/Thread-local_storage#Java.

Si vous ne cochez pas l'option appropriée dans la configuration des servlets, le conteneur servlet utilisera votre servlet avec plusieurs threads pour gérer les requêtes en parallèle. Donc, vous auriez des données distinctes pour chaque thread qui sert les clients.

Si votre WebApplication n'est pas distribuée (s'exécute sur plusieurs machines virtuelles Java), vous pouvez utiliser l'objet ServletContext pour stocker des données partagées entre les requêtes et les threads (assurez-vous d'effectuer un verrouillage correct).

+0

En effet. Dans un projet précédent, j'ai stocké le ticket d'un utilisateur dans sa session et créé un filtre pour transférer le ticket de la session vers un thread local pour m'assurer que l'état d'authentification d'un utilisateur était toujours disponible pour le thread traitant la requête. – Julie

0

Les variables Threadlocal sont toujours définies pour être accessibles globalement, car il s'agit de transmettre de manière transparente des informations autour d'un système accessible n'importe où. La valeur de la variable est liée au thread sur lequel elle est définie, donc même si la variable est globale, elle peut avoir des valeurs différentes en fonction du thread à partir duquel elle est accédée.

Un exemple simple consisterait à affecter une chaîne d'identité d'utilisateur à un thread dans une variable locale de threads lorsque la demande est reçue dans la servlet. Partout le long de la chaîne de traitement de cette requête (en supposant qu'il se trouve sur le même thread dans la même machine virtuelle), l'identité peut être récupérée en accédant à cette variable globale. Il serait également important de supprimer cette valeur lorsque la requête est traitée, car le thread sera remis dans un pool de threads.

2

Comme le dit Adiel, la meilleure façon de le faire est probablement d'utiliser le contexte de demande (c'est-à-dire HttpServletRequest), et non de créer un ThreadLocal. Bien qu'il soit certainement possible d'utiliser un ThreadLocal ici, vous devez faire attention à nettoyer votre thread si vous le faites, sinon la requête suivante qui obtient le thread verra la valeur associée à la requête précédente. (Lorsque la première requête est faite avec le thread, le thread retournera dans le pool et ainsi la requête suivante le verra.) Aucune raison de devoir gérer ce genre de chose quand le contexte de la requête existe justement dans ce but.

+0

Vous pouvez également utiliser un filtre de servlet pour gérer le ThreadLocal, au moins la création/nettoyage serait en un seul endroit. – sehugg

+1

-1 il y a certainement une bonne raison pour "gérer ce genre de chose", il y a une différence entre passer 1000 fois autour de votre application, par rapport à avoir juste un getter statique ;-) – peenut

+1

Je ne comprends pas votre commentaire. Ma réponse n'a rien à voir avec le fait de passer un argument autour de 1000 fois ou un getter statique. Il s'agit plutôt du choix entre utiliser le stockage ThreadLocal vs HttpServletRequest comme contexte pour les requêtes HTTP. Étant donné que l'OP souhaite que les liaisons durent pendant la durée de la demande, le contexte approprié est le HSR (cycle de vie coïncidant avec la demande), pas ThreadLocal (partagé entre les requêtes puisque les threads de travail sont généralement regroupés). HSR vous permet d'éviter de nettoyer le contexte car il est ignoré à la fin de la requête. –

4

Réponse courte: Oui.
Un peu plus long: Voici comment Spring fait sa magie. Voir RequestContextHolder (via DocJar).

La prudence s'impose cependant - vous devez savoir quand invalider le ThreadLocal, comment s'en remettre à d'autres threads et comment (pas) s'emmêler avec un contexte non-threadlocal.

Ou vous pouvez simplement utiliser Spring ...

+0

+1 réponse au point! – peenut

1

En utilisant ThreadLocal pour stocker des informations scope demande a le potentiel de briser si vous utilisez Servlet 3.0 (ou demandes mises en suspension Jetty continuations) En utilisant plusieurs threads de ceux API traitent un seul demande.