Anatomía de ThreadLocal

En circunstancias normales, cualquier hilo puede acceder y modificar las variables que creamos. Esto dará lugar a una serie de problemas. Por ejemplo, si dos personas van a trabajar, si dos personas comparten la misma cuenta para ahorrar dinero, inevitablemente surgirán algunas disputas en el futuro. La mejor solución es asignar una a cada una de las Cuenta, de esta manera evitar disputas.

Esta promoción a subprocesos consiste en utilizar ThreadLoad para evitar la competencia entre subprocesos.

Principios de ThreadLocal, puntos a tener en cuenta al usar y cuáles son los escenarios de aplicación.

Responda los cuatro puntos principales:

  • ¿Qué es ThreadLocal?
  • Principio ThreadLocal
  • Puntos a tener en cuenta al usar ThreadLocal
  • Escenarios de aplicación de ThreadLocal

¿Qué es ThreadLocal?

ThreadLocal, la variable local del hilo. Si crea una variable ThreadLocal, todos los subprocesos que accedan a esta variable tendrán una copia local de esta variable. Cuando varios subprocesos manipulan esta variable, en realidad manipulan las variables en su propia memoria local para aislarlos. Función para evitar problemas de seguridad de subprocesos .

//创建一个ThreadLocal变量
static ThreadLocal<String> localVariable = new ThreadLocal<>();

Principio ThreadLocal

Diagrama de estructura de memoria ThreadLocal:

imagenSe puede ver en el diagrama de estructura:

  • El objeto Thread contiene una variable miembro de ThreadLocal.ThreadLocalMap.
  • ThreadLocalMap mantiene una matriz de Entry internamente, cada entrada representa un objeto completo, la clave es el propio ThreadLocal y el valor es el valor genérico de ThreadLocal.

Es más fácil de entender comparando varios códigos fuente clave.

public class Thread implements Runnable {
 ......
//与此线程有关的ThreadLocal值。由ThreadLocal类维护
ThreadLocal.ThreadLocalMap threadLocals = null;

//与此线程有关的InheritableThreadLocal值。由InheritableThreadLocal类维护
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
 ......
}

A partir del código fuente de la clase Thread, podemos ver que hay una variable threadLocals y una variable hereitableThreadLocals en la clase Thread, las cuales son variables del tipo ThreadLocalMap.

Los métodos clave set () y get () en ThreadLocal

public void set(T value) {
        Thread t = Thread.currentThread(); //获取当前线程t
        ThreadLocalMap map = getMap(t);  //根据当前线程获取到ThreadLocalMap
        if (map != null)
            map.set(this, value); //K,V设置到ThreadLocalMap中
        else
            createMap(t, value); //创建一个新的ThreadLocalMap
    }
    public T get() {
        Thread t = Thread.currentThread();//获取当前线程t
        ThreadLocalMap map = getMap(t);//根据当前线程获取到ThreadLocalMap
        if (map != null) {
            //由this(即ThreadLoca对象)得到对应的Value,即ThreadLocal的泛型值
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value; 
                return result;
            }
        }
        return setInitialValue();
    }

Por el código fuente, sabemos que la variable final se almacena en el ThreadLocalMap del hilo actual, no en Threadlocal.

Cada Thread tiene un ThreadLocalMap, y ThreadLocal puede almacenar pares clave-valor con ThreadLocal como clave y Object como valor.

Matriz de entrada de ThreadLocalMap

static class ThreadLocalMap {
    static class Entry extends WeakReference<ThreadLocal<?>> {
        /** The value associated with this ThreadLocal. */
        Object value;
        Entry(ThreadLocal<?> k, Object v) {
            super(k);
            value = v;
        }
    }
}

Entonces, ¿cómo respondes ** "El principio de implementación ThreadLocal" **? De la siguiente manera, es mejor combinar el diagrama de estructura anterior para explicar

  • La clase Thread tiene una variable de instancia threadLocals de tipo ThreadLocal.ThreadLocalMap, es decir, cada hilo tiene su propio ThreadLocalMap.
  • ThreadLocalMap mantiene una matriz de Entry internamente, cada entrada representa un objeto completo, la clave es el propio ThreadLocal y el valor es el valor genérico de ThreadLocal.
  • Cuando cada hilo establece un valor en ThreadLocal, lo almacena en su propio ThreadLocalMap y lo lee con un determinado ThreadLocal como referencia, y encuentra la clave correspondiente en su propio mapa, realizando así el aislamiento del hilo.

Problema de pérdida de memoria ThreadLocal

Echemos un vistazo al diagrama de referencia de TreadLocal:

imagen

La clave utilizada en ThreadLocalMap es una referencia débil de ThreadLocal, y el valor es una referencia fuerte, como sigueimagen

Referencia débil: mientras se ejecute el mecanismo de recolección de basura, independientemente de si el espacio de memoria de la JVM es suficiente, se reclamará la memoria ocupada por el objeto.

Las referencias débiles son más fáciles de reciclar. Por lo tanto, si ThreadLocal (Key of ThreadLocalMap) es reciclado por el recolector de basura, pero debido a que el ciclo de vida de ThreadLocalMap es el mismo que el de Thread, si no se recicla en este momento, ocurrirá esta situación: la clave de ThreadLocalMap es desaparecido, y el valor sigue siendo Ahora, esto "causará un problema de pérdida de memoria" . ¿Cómo "solucionar el problema de la pérdida de memoria" **? Después de usar ThreadLocal, llame al método remove () a tiempo para liberar espacio en la memoria.

Escenarios de aplicación de ThreadLocal

  • Grupo de conexiones de base de datos
  • Utilizado en la gestión de sesiones

Por fin

  • Si siente que ha sido recompensado después de leerlo, espero que me apruebe. Esta será la mayor motivación para actualizar. Gracias por su apoyo.
  • Bienvenidos a todos para que presten atención a mi cuenta pública [Java Fox], enfocándome en los conocimientos básicos de Java y la computadora, prometo dejarles obtener algo después de leerlo, si no me creen, péguenme
  • Si tiene diferentes opiniones o sugerencias después de leer, por favor comente y comparta con nosotros. Gracias por su apoyo y cariño.

——Soy Chuhu, y amo la programación tanto como a ti.

imagen

Supongo que te gusta

Origin blog.csdn.net/issunmingzhi/article/details/111614850
Recomendado
Clasificación