Preguntas sobre el uso de ThreadLocal en un servicio de alcance singleton de Spring

1) El código de ejemplo está bien, excepto por los conflictos de nombres en doB y doC donde está utilizando el mismo nombre para la variable estática que hace referencia a ThreadLocal como lo es para la variable local que contiene lo que extrae de ThreadLocal.

2) El objeto que almacena en ThreadLocal permanece adjunto a ese hilo hasta que se elimine explícitamente. Si su servicio se ejecuta en un contenedor de servlet, por ejemplo, cuando una solicitud completa su hilo regresa al grupo. Si no ha limpiado el contenido de la variable ThreadLocal del hilo, esos datos se mantendrán para acompañar cualquier solicitud que el hilo se asigne a continuación. Cada hilo es una raíz GC, las variables locales de hilo unidas al hilo no se recolectarán basura hasta después de que el hilo muera. Según el documento de API :

Cada subproceso tiene una referencia implícita a su copia de una variable local de subproceso siempre que el subproceso esté activo y la instancia de ThreadLocal esté accesible; después de que un subproceso desaparece, todas sus copias de instancias locales de subprocesos están sujetas a recolección de elementos no utilizados (a menos que existan otras referencias a estas copias).

Si su información de contexto está limitada al alcance de un servicio, es mejor que pase la información a través de parámetros en lugar de usar ThreadLocal. ThreadLocal es para casos en que la información debe estar disponible en diferentes servicios o en diferentes capas, parece que solo está complicando demasiado su código si solo lo usará un servicio. Ahora, si tiene datos que serían utilizados por los consejos de AOP en diferentes objetos dispares, colocar esos datos en un hilo local podría ser un uso válido.

Para realizar la limpieza, normalmente identificaría un punto en el que el subproceso se realiza con el procesamiento actual, por ejemplo, en un filtro de servlet, donde la variable local del subproceso se puede eliminar antes de que el subproceso se devuelva al conjunto de subprocesos. No usaría un bloque try-finally porque el lugar donde inserta el objeto threadlocal no está cerca de donde lo está limpiando.

Respuesta 1

Cuando usa un ThreadLocaldebe asegurarse de limpiarlo pase lo que pase porque:

  1. Crea de alguna manera una pérdida de memoria ya que el GC no puede recopilar el valor porque un objeto es elegible para el GC si y solo si ya no hay ningún objeto que tenga una referencia directa o indirecta al objeto. Entonces, por ejemplo, aquí, su ThreadLocalinstancia tiene indirectamente una referencia dura a su valor, aunque es interna ThreadLocalMap, la única forma de deshacerse de esta referencia dura es llamar ThreadLocalMap#remove()ya que eliminará el valor de ThreadLocalMap. La otra forma potencial de hacer que su valor sea elegible para el GC sería el caso en que su ThreadLocalinstancia sea elegible para el GC, pero aquí es una constante en la clase, Servicepor lo que nunca será elegible para el GC, que es lo que queremos en su caso. Entonces, la única forma esperada es llamar ThreadLocalMap#remove().
  2. Crea errores difíciles de encontrar porque la mayoría de las veces el subproceso que usa su ThreadLocalforma parte de un thread pooltal que el subproceso se reutilizará para otra solicitud, por lo que si ThreadLocalno se ha limpiado adecuadamente, el subproceso reutilizará la instancia de su objeto almacenado en su ThreadLocalque potencialmente ni siquiera está relacionado con la nueva solicitud que conduce a errores complejos. Entonces, por ejemplo, podríamos obtener el resultado de un usuario diferente solo porque ThreadLocalno se ha limpiado.

Entonces el patrón es el siguiente:

try {
    userInfo.set(new UserInfo(userId, name));
    // Some code here 
} finally {
    // Clean up your thread local whatever happens
    userInfo.remove();
}

Acerca de la seguridad de subprocesos, por supuesto, es seguro para subprocesos incluso si UserInfono es seguro para subprocesos porque cada subproceso usará su propia instancia, por UserInfolo que no se accederá o modificará ninguna instancia de UserInfoalmacenado en ThreadLocalvarios subprocesos porque de ThreadLocalalguna manera un valor tiene el alcance del subproceso actual .

Respuesta: 2

Me gustaría saber si es posible agregar una línea en un archivo con Java. Por ejemplo, myFile: 1: línea 1 2: línea 2 3: línea 3 4: línea 4 Me gustaría agregar un ejemplo de línea zorro en la tercera línea para que ...

Hoy, cuando estaba leyendo mis notas de clase, no entiendo cuál es el propósito de extender en este contexto. Considere este código: import java.net. *; import java.awt. *; clase pública QueenApl ...

Estoy trabajando en una empresa que es nueva en Java y soy el único programador de Java y necesito escribir sobre 10 sistemas en unos pocos meses. La empresa tiene otros 2 programadores que conocen Java básico. No ...

He leído este enlace sobre GetByteArrayElements: Preguntas frecuentes: ¿Cómo comparto datos en bruto con código nativo? http://developer.android.com/training/articles/perf-jni.html Dijo que GetByteArrayElements ...