Estaba leyendo JavaDoc para Threadlocal aquí
https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ThreadLocal.html
y dice "Las instancias ThreadLocal son típicamente campos estáticos privados en clases que desean asociar el estado con un hilo (por ejemplo, un ID de usuario o un ID de transacción)".
Pero mi pregunta es ¿por qué eligieron hacerlo estático (normalmente) - hace que las cosas sean un poco confusas tener un estado "por hilo" pero los campos son estáticos?
fuente
ThreadLocal
para mantener una referencia a un conjunto de hash que mapea objetos a instancias por subproceso.ThreadLocal
contendría sus propios datos locales de subproceso incluso si esasThreadLocal
instancias existen en el mismo subproceso. No es necesariamente incorrecto hacer eso, supongo que podría ser el patrón menos popular de los dosHágalo estático o si está tratando de evitar cualquier campo estático en su clase, haga que la clase en sí sea un singleton y luego puede usar de manera segura el ThreadLocal de nivel de instancia siempre que tenga ese singleton disponible globalmente.
fuente
No tiene por qué serlo. Lo importante es que debe ser singleton.
fuente
La razón es que se accede a las variables a través de un puntero asociado con el hilo. Actúan como variables globales con alcance de hilo, por lo tanto, estático es el ajuste más cercano. Esta es la forma en que obtiene el estado local del hilo en cosas como pthreads, por lo que esto podría ser un accidente del historial y la implementación.
fuente
Un uso de un threadlocal en una instancia por subproceso es si desea que algo sea visible en todos los métodos de un objeto y que sea seguro para subprocesos sin sincronizar el acceso a él como lo haría para un campo ordinario.
fuente
Refiérase a esto , esto le dará una mejor comprensión.
En resumen, el
ThreadLocal
objeto funciona como un mapa clave-valor. Cuando elThreadLocal
get/set
método de invocación del hilo , recuperará / almacenará el objeto del hilo en la clave del mapa y el valor en el valor del mapa. Es por eso que diferentes subprocesos tienen diferentes copias de valor (que desea almacenar localmente), porque residen en diferentes entradas de mapas.Es por eso que solo necesita un mapa para mantener todos los valores. Aunque no es necesario, puede tener múltiples mapas (sin declarar estático) para mantener cada objeto de hilo también, lo cual es totalmente redundante, por eso se prefiere la variable estática.
fuente
static final ThreadLocal
las variables son seguras para subprocesos.static
hace que la variable ThreadLocal esté disponible en varias clases solo para el hilo respectivo. es una especie de decantación de variable global de las respectivas variables locales de subproceso en múltiples clases.Podemos comprobar la seguridad de este subproceso con el siguiente ejemplo de código.
CurrentUser
- almacena la identificación del usuario actual en ThreadLocalTestService
- Servicio simple con método:getUser()
para recuperar el usuario actual de CurrentUser.TestThread
- esta clase se usa para crear múltiples subprocesos y establecer ID de usuario al mismo tiempo.
.
.
Ejecute la clase principal TestThread. Salida -
Resumen de análisis
main
la ejecución finaliza e imprime el usuario actual como "62", laForkJoinPool.commonPool-worker-1
ejecución paralela finaliza e imprime el usuario actual como "87", laForkJoinPool.commonPool-worker-2
ejecución paralela termina e imprime el usuario actual como "31", laForkJoinPool.commonPool-worker-3
ejecución paralela termina e imprime el usuario actual como "81"Inferencia
Los subprocesos concurrentes pueden recuperar los ID de usuario correctos incluso si se han declarado como "ThreadLocal final estático"
fuente