La clase ThreadLocal puede entenderse como ThreadLocalVariable (variable local de subproceso), que proporciona interfaces de acceso o métodos como get y set. Estos métodos almacenan una copia independiente para cada subproceso que usa la variable, por lo que get siempre devuelve la ubicación de la ejecución actual. hilo. El último valor establecido al llamar a set. Se puede considerar que ThreadLocal<T> contiene un objeto Map<Thread,T>, que contiene valores específicos de ese hilo.
En resumen, para el problema del intercambio de recursos de múltiples subprocesos, el mecanismo de sincronización adopta el método de "intercambiar tiempo por espacio", mientras que ThreadLocal adopta el método de "intercambiar espacio por tiempo". El primero solo proporciona una copia de la variable para que diferentes subprocesos se pongan en cola para acceder, mientras que el segundo proporciona una copia de la variable para cada subproceso, por lo que se puede acceder a ella al mismo tiempo sin afectarse entre sí.
Hilo simuladoLocal
Copie el código de código de la siguiente manera:
importar java.util.Collections;
importar java.util.HashMap;
importar java.util.Map;
clase pública SimpleThreadLocal<T> {
Mapa privado<Subproceso, T> valorMap = Colecciones
.synchronizedMap(new HashMap<Thread, T>());
conjunto de vacío público (T nuevoValor) {
valueMap.put(Thread.currentThread(), newValue); // ①La clave es el objeto del hilo y el valor es una copia de la variable de este hilo.
}
público T get() {
Hilo currentThread = Thread.currentThread();
T o = valueMap.get(currentThread); // ② Devuelve la variable correspondiente a este hilo
if (o == null && !valueMap.containsKey(currentThread)) { // ③Si no existe en el Mapa, colóquelo en el Mapa y guárdelo.
o = valor inicial();
valueMap.put(currentThread, o);
}
volver o;
}
eliminación de vacío público() {
valueMap.remove(Thread.currentThread());
}
protegido T valor inicial() {
devolver nulo;
}
}
UtilidadHiloLocal
Copie el código de código de la siguiente manera:
clase contar {
privado SimpleThreadLocal<Integer> cuenta = nuevo SimpleThreadLocal<Integer>() {
@Anular
Valor inicial entero protegido() {
devolver 0;
}
};
aumento de entero público() {
contar.set(count.get() + 1);
volver contar.get();
}
}
clase TestThread implementa Runnable {
recuento privado;
TestThread público (recuento de recuento) {
this.count = contar;
}
@Anular
ejecución pública vacía () {
// TODO Código auxiliar de método generado automáticamente
para (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + "/t" + i
+ "th/t" + count.increase());
}
}
}
clase pública TestThreadLocal {
público estático vacío principal (String [] argumentos) {
Contar conteo = nuevo Contar();
Hilo t1 = nuevo hilo (nuevo TestThread (recuento));
Hilo t2 = nuevo hilo (nuevo TestThread (recuento));
Hilo t3 = nuevo hilo (nuevo TestThread (recuento));
Hilo t4 = nuevo hilo (nuevo TestThread (recuento));
t1.inicio();
t2.start();
t3.start();
t4.start();
}
}
El código de copia de salida es el siguiente:
Hilo-0 1º 1
Hilo-0 2º 2
Hilo-0 3º 3
Hilo-3 1º 1
Hilo-1 1º 1
Hilo-1 2º 2
Hilo-2 1º 1
Hilo-1 3º 3
Hilo-3 2º 2
Hilo-3 3º 3
Hilo-2 2º 2
Hilo-2 3º 3