Lo que ThreadLocal? Y cómo utilizar ThreadLocal, la forma de utilizar el servicio

Lo que es ThreadLocal

Como primera versión del JDK 1.2 proporciona java.lang.ThreadLocal, ThreadLocal proporcionar una nueva forma de resolver el problema de los programas concurrentes multi-hilo. El uso de esta herramienta puede ser clase muy simple para escribir una hermosa programas multihilo.

Cuando se utiliza de mantenimiento variable de ThreadLocal, ThreadLocal proporcionan para cada hilo utilizando la copia variable independiente variable, cada hilo puede cambiar de forma independiente su copia sin afectar a otros hilos de copia correspondientes.

Desde la perspectiva de la rosca de vista, la variable de destino es como una variable local de rosca, que está destinado a expresar el nombre de clase "local".

Por lo tanto, el código para escribir las variables de subproceso local en Java que sea relativamente pocos torpe, causando por lo tanto las variables de subproceso local no están bien en la popularidad de los desarrolladores de Java en.

métodos de interfaz ThreadLocal

ThreadLocal interfaz de clase es muy simple, sólo cuatro métodos, vamos a echar un vistazo:

  • sin efecto conjunto (Object value) valor de las variables locales hilo del hilo actual.

  • get public Object () devuelve el método del hilo de corriente correspondiente a las variables de subproceso local.

  • público Remove void () el valor de las variables locales del subproceso actual borrada, el propósito es reducir el uso de memoria, que es un nuevo método para JDK 5.0. Cabe señalar que, cuando el extremo del hilo, la variable local hilo debe ser automáticamente la basura, por lo que pide explícitamente este método para limpiar el hilo no se requiere variable local para operar, pero puede acelerar la recuperación de la velocidad de la memoria.

  • Objeto protegido initialValue () vuelve al valor inicial de las variables locales de hilo, que es un método de una subclases cubierta diseñada protegido, aparentemente para permitir. Este método es un método para llamadas de demora, get llamada () o conjunto (Objeto) cuando la ejecución del hilo por primera vez, y sólo realiza una vez. El valor por defecto en los retornos directos ThreadLocal un nulo.

Vale la pena mencionar que en JDK5.0, ThreadLocal tiene soporte para los genéricos, la clase del nombre de la clase se ha convertido en ThreadLocal. métodos de la API ha ajustado en consecuencia, la nueva versión de los métodos de la API son conjunto vacío (valor T), T get () y T initialValue ().

1, la definición de

las variables de subproceso local ThreadLocal, un contenedor de almacenamiento es variable, este recipiente se almacena en variables pueden ser tomadas en cualquier posición de la rosca variable.

las variables ThreadLocal en el uso de hilos separados, otros hilos no pueden ser utilizados para garantizar la seguridad de las variables

2, Ejemplo

public class TestDemo {
	//用一个静态的变量来记录ThreadLocal对象,方法在任何地方法直接调用
	static ThreadLocal<String> local = new ThreadLocal<>();
	public static void main(String[] args) {
		new Thread(){
			public void run(){
				//在线程的任意地方设置变量
				local.set("你");
				method();
			}
		}.start();
		new Thread(){
			public void run(){
				local.set("好");
				method();
			}
		}.start();
	}
	public static void method(){
		//可以在当前线程的任意地方获取变量
		System.out.println(local.get());
	}
}

3. necesidades empresariales prácticas

Cuando un dispositivo de dos de interfaz de devolución de llamada asincrónica, los datos son para el mismo registro, para garantizar la integridad de los datos, ¿cómo lo haría?

interfaces conocidas callback orden aleatorio, no se puede saber qué devolución de llamada para ejecutar

Estructura de la tabla:

Identificación del nombre num

Dos parámetros de devolución de llamada es el regreso de un campo de la tabla

Por ejemplo:

Devolver un campo num interfaz de devolución de llamada

campo de nombre de la interfaz de devolución de llamada de retorno de dos

Ellos no tienen una identidad común, pero aún tiene que haber un registro, ¿cómo lo haría?

Mi enfoque es un comienzo:

Para los datos de la consulta en la tabla en los últimos 10 segundos, si no se inserta, si se quiere que las operaciones de actualización
y viceversa otra interfaz de la misma manera, la primera comprobación de si el registro existe, no se inserta, si se quiere que las operaciones de actualización

Pero sus desventajas también son obvias, sólo registra la grabación en cuestión de segundos diez.

Esta vez no con el ThreadLocal

Directamente sobre el código

public class Test {
    //静态类 方便调用
    static ThreadLocal<Ta> local = new ThreadLocal<>();

    public static void main(String[] args) {
        //无论先调用哪个接口 都先将这个值插入到ThreadLocal中
        Ta ta = new Ta();
        ta.setId(1);
        local.set(ta);
        //因为我们不知道哪个回调先调用,所以先判断是否存在了
        if(local.get().getId()!=null){
            //存在的情况就在另一个回调中获取上一个回调中插入的值
            Ta ta1 = new Ta();
            ta1.setId(local.get().getId());
            ta1.setName("成功了");
            //记得再保存数据的时候先remove,再set进去
            local.remove();
            local.set(ta1);
            //这个时候我们就可以插入数据库了,保证了数据的完整性
        }
        method();

    }

    public static void method(){
        //可以在当前线程的任意地方获取变量
        //加上 .toString() 是因为我用的是实体类
        System.out.println(local.get().toString());
    }


    public static class  Ta{
		//实体类
        private  Integer id;
        private  String name;
        private  Integer num;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getNum() {
            return num;
        }

        public void setNum(Integer num) {
            this.num = num;
        }

        @Override
        public String toString() {
            return "Ta{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", num=" + num +
                    '}';
        }
    }
}

Esto completa las necesidades de negocio anterior, que es de un solo subproceso.

4. El uso de ThreadLocal en varios subprocesos

package com.test;  
  
public class TestNum {  
    // ①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值  
    private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {  
        public Integer initialValue() {  
            return 0;  
        }  
    };  
  
    // ②获取下一个序列值  
    public int getNextNum() {  
        seqNum.set(seqNum.get() + 1);  
        return seqNum.get();  
    }  
  
    public static void main(String[] args) {  
        TestNum sn = new TestNum();  
        // ③ 3个线程共享sn,各自产生序列号  
        TestClient t1 = new TestClient(sn);  
        TestClient t2 = new TestClient(sn);  
        TestClient t3 = new TestClient(sn);  
        t1.start();  
        t2.start();  
        t3.start();  
    }  
  
    private static class TestClient extends Thread {  
        private TestNum sn;  
  
        public TestClient(TestNum sn) {  
            this.sn = sn;  
        }  
  
        public void run() {  
            for (int i = 0; i < 3; i++) {  
                // ④每个线程打出3个序列值  
                System.out.println("thread[" + Thread.currentThread().getName() + "] --> sn["  
                         + sn.getNextNum() + "]");  
            }  
        }  
    }  
}  

Definimos la subclase generalmente a modo clases internas anónimas ThreadLocal proporcionar un valor inicial variables, como en el ejemplo mostrado en ①. Generación de un conjunto de hilos TestClient número de secuencia, el al ③, se generaron tres TestClient, comparten la misma instancia TestNum. Al ejecutar el código anterior, los siguientes resultados de salida en la consola:

del hilo [-0] -> sn [1]
del hilo [-1] -> sn [1]
del hilo [-2] -> sn [1]
del hilo [-1] -> sn [ 2]
del hilo [-0] -> sn [2]
del hilo [-1] -> sn [3]
del hilo [-2] -> sn [2]
del hilo [-0] -> sn [3]
del hilo [-2] -> sn [3]

Inspección salida de información de resultado, se encontró que aunque cada ID del hilo generado comparten el mismo ejemplo TestNum, pero no lo hacen, pueden producirse interferencias, sino que cada número de secuencia generada de forma independiente, esto se debe a que a través de cada ThreadLocal un hilo proporciona copias separadas.

resumen

ThreadLocal problema de seguridad hilo es la manera de resolver una muy buena, que resuelve el problema de los conflictos de acceso concurrente variables, proporcionando un hilo separado para cada copia de la variable. En muchos casos, ThreadLocal que el uso de mecanismos de sincronización hilo sincronizados para solucionar problemas de seguridad más simple, más conveniente, y los resultados del programa tienen una mayor concurrencia.

Liberadas dos artículos originales · ganado elogios 0 · Vistas 26

Supongo que te gusta

Origin blog.csdn.net/weixin_44248755/article/details/104816585
Recomendado
Clasificación