Je lisais le JavaDoc pour Threadlocal ici
https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ThreadLocal.html
et il dit "Les instances ThreadLocal sont généralement des champs statiques privés dans les classes qui souhaitent associer un état à un thread (par exemple, un ID utilisateur ou un ID de transaction)."
Mais ma question est pourquoi ont-ils choisi de le rendre statique (généralement) - cela rend les choses un peu déroutantes d'avoir un état "par thread" mais les champs sont statiques?
la source
ThreadLocal
pour contenir une référence à un ensemble de hachage qui mappe des objets à des instances par thread.ThreadLocal
contiendrait ses propres données locales de thread même si cesThreadLocal
instances existent dans le même thread. Ce n'est pas nécessairement faux de faire cela - je suppose que c'est peut-être le modèle le moins populaire des deuxSoit le rendre statique, soit si vous essayez d'éviter les champs statiques dans votre classe - faites de la classe elle-même un singleton et vous pouvez ensuite utiliser en toute sécurité le ThreadLocal de niveau d'instance tant que ce singleton est disponible globalement.
la source
Ça ne doit pas être. L'important est que ce soit un singleton.
la source
La raison en est que les variables sont accessibles via un pointeur associé au thread. Ils agissent comme des variables globales avec une portée de thread, donc static est la plus proche. C'est ainsi que vous obtenez l'état local des threads dans des choses comme pthreads, donc cela pourrait être un accident de l'historique et de l'implémentation.
la source
Une utilisation d'un threadlocal sur une instance par thread est si vous voulez que quelque chose soit visible dans toutes les méthodes d'un objet et qu'il soit thread-safe sans synchroniser l'accès comme vous le feriez pour un champ ordinaire.
la source
Référez-vous à cela , cela donne une meilleure compréhension.
En bref, l'
ThreadLocal
objet fonctionne comme une carte clé-valeur. Lorsque le thread invoqueThreadLocal
get/set
méthode, il récupère / stocke l'objet thread dans la clé de la carte et la valeur dans la valeur de la carte. C'est pourquoi différents threads ont une valeur copiée différente (que vous souhaitez stocker localement), car elle réside dans l'entrée de la carte différente.C'est pourquoi vous n'avez besoin que d'une seule carte pour conserver toutes les valeurs. Bien que cela ne soit pas nécessaire, vous pouvez avoir plusieurs mappages (sans déclarer statique) pour conserver également chaque objet thread, ce qui est totalement redondant, c'est pourquoi la variable statique est préférée.
la source
static final ThreadLocal
les variables sont thread-safe.static
rend la variable ThreadLocal disponible dans plusieurs classes pour le thread respectif uniquement. c'est une sorte de décaration de variable globale des variables locales de thread respectives à travers plusieurs classes.Nous pouvons vérifier la sécurité de ce thread avec l'exemple de code suivant.
CurrentUser
- stocke l'ID utilisateur actuel dans ThreadLocalTestService
- Service simple avec méthode -getUser()
pour récupérer l'utilisateur actuel de CurrentUser.TestThread
- cette classe utilisée pour créer plusieurs threads et définir des userid simultanément.
.
.
Exécutez la classe principale TestThread. Production -
Résumé de l'analyse
main
l'exécution se termine et imprime l'utilisateur actuel comme "62", parallèlement l'ForkJoinPool.commonPool-worker-1
exécution se termine et imprime l'utilisateur courant comme "87", parallèlement l'ForkJoinPool.commonPool-worker-2
exécution se termine et imprime l'utilisateur actuel comme "31", parallèlement l'ForkJoinPool.commonPool-worker-3
exécution se termine et imprime l'utilisateur actuel comme "81"Inférence
Les threads simultanés sont capables de récupérer les userids corrects même s'ils ont été déclarés comme "statique final ThreadLocal"
la source