Ejemplo de Java ThreadLocal

La clase ThreadLocal de Java se utiliza para crear variables locales de hilo. Sabemos que todos los hilos de un objeto comparten sus variables, por lo que la variable no es segura para subprocesos. Podemos utilizar la sincronización para garantizar la seguridad del hilo, pero si queremos evitarla, podemos utilizar variables ThreadLocal.

ThreadLocal de Java

Cada hilo tiene su propia variable ThreadLocal y puede utilizar los métodos get() y set() para obtener el valor predeterminado o cambiar su valor local al hilo. Las instancias de ThreadLocal suelen ser campos estáticos privados en clases que desean asociar estado con un hilo.

Ejemplo de ThreadLocal en Java

Aquí hay un pequeño ejemplo que muestra el uso de ThreadLocal en un programa Java y demuestra que cada hilo tiene su propia copia de la variable ThreadLocal. ThreadLocalExample.java

package com.journaldev.threads;

import java.text.SimpleDateFormat;
import java.util.Random;

public class ThreadLocalExample implements Runnable{

    // SimpleDateFormat no es seguro para subprocesos, así que dale uno a cada hilo
    private static final ThreadLocal formatter = new ThreadLocal(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };
    
    public static void main(String[] args) throws InterruptedException {
        ThreadLocalExample obj = new ThreadLocalExample();
        for(int i=0 ; i<10; i++){
            Thread t = new Thread(obj, ""+i);
            Thread.sleep(new Random().nextInt(1000));
            t.start();
        }
    }

    @Override
    public void run() {
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern());
        try {
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // el patrón del formateador se cambia aquí por hilo, pero no se reflejará en otros hilos
        formatter.set(new SimpleDateFormat());
        
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
    }

}

El resultado del programa de ejemplo de ThreadLocal en Java anterior es:

Thread Name= 0 default Formatter = yyyyMMdd HHmm
Thread Name= 1 default Formatter = yyyyMMdd HHmm
Thread Name= 0 formatter = M/d/yy h:mm a
Thread Name= 2 default Formatter = yyyyMMdd HHmm
Thread Name= 1 formatter = M/d/yy h:mm a
Thread Name= 3 default Formatter = yyyyMMdd HHmm
Thread Name= 4 default Formatter = yyyyMMdd HHmm
Thread Name= 4 formatter = M/d/yy h:mm a
Thread Name= 5 default Formatter = yyyyMMdd HHmm
Thread Name= 2 formatter = M/d/yy h:mm a
Thread Name= 3 formatter = M/d/yy h:mm a
Thread Name= 6 default Formatter = yyyyMMdd HHmm
Thread Name= 5 formatter = M/d/yy h:mm a
Thread Name= 6 formatter = M/d/yy h:mm a
Thread Name= 7 default Formatter = yyyyMMdd HHmm
Thread Name= 8 default Formatter = yyyyMMdd HHmm
Thread Name= 8 formatter = M/d/yy h:mm a
Thread Name= 7 formatter = M/d/yy h:mm a
Thread Name= 9 default Formatter = yyyyMMdd HHmm
Thread Name= 9 formatter = M/d/yy h:mm a

Como puedes ver en la salida, Thread-0 ha cambiado el valor del formateador, pero aún así, el formateador predeterminado de Thread-2 es el mismo que el valor inicializado. Puedes observar el mismo patrón para otros hilos también. Actualización: La clase ThreadLocal se amplía en Java 8 con un nuevo método withInitial() que toma como argumento la interfaz funcional Supplier. Así que podemos usar expresiones lambda para crear fácilmente la instancia ThreadLocal. Por ejemplo, la variable ThreadLocal del formateador anterior se puede definir en una sola línea de la siguiente manera:

private static final ThreadLocal<SimpleDateFormat> formatter = 
	ThreadLocal.<SimpleDateFormat>withInitial
	(() -> {return new SimpleDateFormat("yyyyMMdd HHmm");});

Si eres nuevo en las características de Java 8, por favor, revisa Java 8 Características y Interfaces Funcionales de Java 8. Eso es todo sobre ThreadLocal en la programación en Java. Referencia: Documentación de la API

Source:
https://www.digitalocean.com/community/tutorials/java-threadlocal-example