¿Cuándo y cómo debo usar una variable ThreadLocal?


¿Cuándo debo usar una variable ThreadLocal?

¿Cómo se usa?

Author: Andrew Tobilko, 2009-05-03

22 answers

Un uso posible (y común) es cuando tienes algún objeto que no es seguro para subprocesos, pero quieres evitar sincronizar el acceso a ese objeto (te estoy mirando, SimpleDateFormat). En su lugar, dale a cada hilo su propia instancia del objeto.

Por ejemplo:

public class Foo
{
    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date)
    {
        return formatter.get().format(date);
    }
}

Documentación.

 786
Author: overthink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-25 17:51:39

Dado que un ThreadLocal es una referencia a los datos dentro de un Thread dado, puede terminar con fugas de carga de clases al usar ThreadLocal s en servidores de aplicaciones que usan grupos de subprocesos. Debe tener mucho cuidado al limpiar cualquier ThreadLocals que get() o set() utilizando el método ThreadLocal's remove().

Si no limpia cuando haya terminado, cualquier referencia que tenga a clases cargadas como parte de una aplicación web desplegada permanecerá en el montón permanente y nunca obtendrá basura recolectada. Redesploying / undeploying la aplicación web no limpiará cada Thread's referencia a la clase de su aplicación web(es) ya que el Thread no es algo propiedad de su aplicación web. Cada despliegue sucesivo creará una nueva instancia de la clase que nunca será recogida como basura.

Terminará con excepciones de memoria fuera debido a java.lang.OutOfMemoryError: PermGen space y después de un poco de búsqueda en google probablemente solo aumentará -XX:MaxPermSize en lugar de corregir el error.

Si terminas experimentando estos problemas, puedes determine qué hilo y clase está reteniendo estas referencias usando el Analizador de memoria de Eclipse y/o siguiendo la guía de Frank Kieviet y el seguimiento.

Actualización: Re-descubierto entrada de blog de Alex Vasseur que me ayudó a rastrear algunos ThreadLocal problemas que estaba teniendo.

 381
Author: Phil M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-27 22:42:09

Muchos frameworks usan ThreadLocals para mantener algún contexto relacionado con el subproceso actual. Por ejemplo, cuando la transacción actual se almacena en un ThreadLocal, no es necesario pasarla como parámetro a través de cada llamada de método, en caso de que alguien de la pila necesite acceso a ella. Las aplicaciones web pueden almacenar información sobre la solicitud y la sesión actuales en un ThreadLocal, para que la aplicación tenga fácil acceso a ellas. Con Guice puedes usar ThreadLocals al implementar custom scopes para los objetos inyectados (los scopes servlet predeterminados de Guice probablemente también los usen).

ThreadLocals son un tipo de variables globales (aunque ligeramente menos malas porque están restringidas a un hilo), por lo que debe tener cuidado al usarlos para evitar efectos secundarios no deseados y fugas de memoria. Diseñe sus API para que los valores ThreadLocal siempre se borren automáticamente cuando ya no sean necesarios y que no se utilice incorrectamente la API posible (por ejemplo así). ThreadLocals se pueden usar para hacer el código más limpio, y en algunos casos raros son la única manera de hacer que algo funcione (mi proyecto actual tenía dos casos de este tipo; están documentados aquí en "Campos Estáticos y Variables globales").

 125
Author: Esko Luontola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-14 06:46:54

En Java, si tiene un datum que puede variar por hilo, sus opciones son pasar ese datum a cada método que lo necesite (o pueda necesitarlo), o asociar el datum con el hilo. Pasar el dato por todas partes puede ser viable si todos sus métodos ya necesitan pasar una variable de "contexto" común.

Si ese no es el caso, es posible que no desee desordenar las firmas de sus métodos con un parámetro adicional. En un mundo sin hilos, podrías resolver el problema con el equivalente Java de una variable global. En una palabra enhebrada, el equivalente de una variable global es una variable thread-local.

 43
Author: user100464,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-03 20:20:39

Esencialmente, cuando necesita que el valor de una variable dependa del hilo actualy no es conveniente que adjunte el valor al hilo de alguna otra manera (por ejemplo, subproceso de subclase).

Un caso típico es cuando algún otro framework ha creado el thread en el que se está ejecutando su código, por ejemplo, un contenedor servlet, o donde simplemente tiene más sentido usar ThreadLocal porque su variable está entonces "en su lugar lógico" (en lugar de una variable colgando de una subclase de hilo o en algún otro mapa hash).

En mi sitio web, tengo más discusión y ejemplos de cuándo usar ThreadLocal que también pueden ser de interés.

Algunas personas abogan por usar ThreadLocal como una forma de adjuntar un "ID de hilo" a cada hilo en ciertos algoritmos concurrentes donde se necesita un número de hilo (véase, por ejemplo, Herlihy & Shavit). En tales casos, compruebe que realmente está recibiendo un beneficio!

 13
Author: Neil Coffey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-03 23:50:05

Hay un muy buen ejemplo en book Java Concurrency in Practice. Donde el autor ( Joshua Bloch ) explica cómo el confinamiento del hilo es una de las formas más simples de lograr la seguridad del hilo y ThreadLocal es un medio más formal de mantener el confinamiento del hilo. Al final, también explica cómo la gente puede abusar de ella usándola como variables globales.

He copiado el texto del libro mencionado pero falta el código 3.10 ya que no es muy importante entenderlo donde se debe usar ThreadLocal.

Las variables Thread-local a menudo se usan para evitar compartir diseños basados en Singletons mutables o variables globales. Por ejemplo, una aplicación de subproceso único puede mantener una conexión de base de datos global que se inicializa al inicio para evitar tener que pasar una conexión a cada método. Dado que las conexiones JDBC pueden no ser seguras para subprocesos, una aplicación multiproceso que utiliza una conexión global sin coordinación adicional no es segura para subprocesos bien. Al usar un ThreadLocal para almacenar la conexión JDBC, como en ConnectionHolder en Listing 3.10, cada subproceso tendrá su propia conexión.

ThreadLocal se usa ampliamente en la implementación de marcos de aplicación. Por ejemplo, los contenedores J2EE asocian un contexto de transacción con un subproceso de ejecución durante la duración de una llamada EJB. Esto se implementa fácilmente utilizando un subproceso estático local que contiene el contexto de la transacción: cuando el código del marco necesita determinar qué transacción es actualmente en ejecución, obtiene el contexto de la transacción de este ThreadLocal. Esto es conveniente ya que reduce la necesidad de pasar información de contexto de ejecución a cada método, pero acopla cualquier código que use este mecanismo al framework.

Es fácil abusar de ThreadLocal al tratar su propiedad de confinamiento de hilo como una licencia para usar variables globales o como un medio para crear argumentos de método "ocultos". Al igual que las variables globales, las variables thread-local pueden reusability and introduce hidden couplings among classes, and should therefore be used with care.

 11
Author: Rakesh Chauhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-28 14:28:38

La documentación lo dice muy bien: "cada hilo que accede a [una variable local de hilo] (a través de su método get o set) tiene su propia copia inicializada independientemente de la variable".

Se usa uno cuando cada hilo debe tener su propia copia de algo. De forma predeterminada, los datos se comparten entre subprocesos.

 9
Author: RichieHindle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-27 13:31:34

El servidor Webapp puede mantener un grupo de subprocesos, y un var ThreadLocal debe eliminarse antes de la respuesta al cliente, por lo que el subproceso actual puede reutilizarse en la siguiente solicitud.

 9
Author: znlyj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-29 11:58:13
  1. ThreadLocal en Java se había introducido en JDK 1.2, pero más tarde se generalizó en JDK 1.5 para introducir la seguridad de tipo en la variable ThreadLocal.

  2. ThreadLocal se puede asociar con el ámbito del subproceso, todo el código que se ejecuta por Thread tiene acceso a las variables ThreadLocal, pero dos thread no pueden verse entre sí variable ThreadLocal.

  3. Cada hilo contiene una copia exclusiva de la variable ThreadLocal que se convierte en elegible para la recolección de basura después thread terminado o muerto, normalmente o debido a cualquier Excepción, Dado que la variable ThreadLocal no tiene ninguna otra referencia viva.

  4. Las variables ThreadLocal en Java son generalmente campos estáticos privados en Clases y mantienen su estado dentro de Thread.

Leer más: http://javarevisited.blogspot.com/2012/05/how-to-use-threadlocal-in-java-benefits.html#ixzz2XltgbHTK

 8
Author: Abhijit Gaikwad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-13 09:59:38

Dos casos de uso donde se puede usar la variable threadlocal -
1 - Cuando tenemos un requisito para asociar el estado con un hilo (por ejemplo, un ID de usuario o ID de transacción). Eso suele suceder con una aplicación web que cada solicitud que va a un servlet tiene un TransactionID único asociado a ella.

// This class will provide a thread local variable which
// will provide a unique ID for each thread
class ThreadId {
    // Atomic integer containing the next thread ID to be assigned
    private static final AtomicInteger nextId = new AtomicInteger(0);

    // Thread local variable containing each thread's ID
    private static final ThreadLocal<Integer> threadId =
        ThreadLocal.<Integer>withInitial(()-> {return nextId.getAndIncrement();});

    // Returns the current thread's unique ID, assigning it if necessary
    public static int get() {
        return threadId.get();
    }
}

Tenga en cuenta que aquí el método withInitial se implementa utilizando la expresión lambda.
2-Otro caso de uso es cuando queremos tener una instancia de thread safe y no queremos usar sincronización como el costo de rendimiento con la sincronización es más. Uno de estos casos es cuando se utiliza SimpleDateFormat. Dado que SimpleDateFormat no es seguro para roscas, tenemos que proporcionar un mecanismo para que sea seguro para roscas.

public class ThreadLocalDemo1 implements Runnable {
    // threadlocal variable is created
    private static final ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue(){
            System.out.println("Initializing SimpleDateFormat for - " + Thread.currentThread().getName() );
            return new SimpleDateFormat("dd/MM/yyyy");
        }
    };

    public static void main(String[] args) {
        ThreadLocalDemo1 td = new ThreadLocalDemo1();
        // Two threads are created
        Thread t1 = new Thread(td, "Thread-1");
        Thread t2 = new Thread(td, "Thread-2");
        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        System.out.println("Thread run execution started for " + Thread.currentThread().getName());
        System.out.println("Date formatter pattern is  " + dateFormat.get().toPattern());
        System.out.println("Formatted date is " + dateFormat.get().format(new Date()));
    } 

}
 6
Author: infoj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-29 15:21:25

Hay que tener mucho cuidado con el patrón ThreadLocal. Hay algunos aspectos negativos importantes como Phil mencionado, pero uno que no se mencionó es asegurarse de que el código que establece el contexto ThreadLocal no es "reentrante"."

Pueden ocurrir cosas malas cuando el código que establece la información se ejecuta por segunda o tercera vez porque la información en tu hilo puede comenzar a mutar cuando no lo esperabas. Así que tenga cuidado de asegurarse de que la información ThreadLocal no se ha establecido antes de que lo vuelvas a configurar.

 4
Author: Jeff Richley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-23 18:50:09

Nada realmente nuevo aquí, pero hoy descubrí que ThreadLocal es muy útil cuando se usa la validación de Bean en una aplicación web. Los mensajes de validación están localizados, pero por defecto usan Locale.getDefault(). Puede configurar el Validator con un MessageInterpolator diferente, pero no hay forma de especificar el Locale cuando llame a validate. Por lo tanto, podría crear un ThreadLocal<Locale> estático (o mejor aún, un contenedor general con otras cosas que podría necesitar ser ThreadLocal y luego hacer que su MessageInterpolator personalizado elija el Locale de eso. El siguiente paso es escriba un ServletFilter que use un valor de sesión o request.getLocale() para elegir la configuración regional y almacenarla en su referencia ThreadLocal.

 3
Author: Colselaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-31 01:37:35

Como fue mencionado por @unknown (google), su uso es definir una variable global en la que el valor referenciado puede ser único en cada hilo. Sus usos típicamente implican almacenar algún tipo de información contextual que está vinculada al hilo actual de ejecución.

Lo usamos en un entorno Java EE para pasar la identidad de usuario a clases que no son conscientes de Java EE (no tienen acceso a HttpSession, o el EJB SessionContext). De esta manera el código, que hace uso de la identidad para las operaciones basadas en seguridad, pueden acceder a la identidad desde cualquier lugar, sin tener que pasarla explícitamente en cada llamada de método.

El ciclo de operaciones de solicitud/respuesta en la mayoría de las llamadas a Java EE hace que este tipo de uso sea fácil, ya que proporciona puntos de entrada y salida bien definidos para establecer y desactivar el ThreadLocal.

 3
Author: Robin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-27 08:12:53

ThreadLocal asegurará el acceso al objeto mutable por el múltiplo los hilos en el método no sincronizado se sincronizan, significa hacer el objeto mutable debe ser inmutable dentro del método.

Este se logra dando una nueva instancia de objeto mutable para cada hilo intenta acceder a él. Por lo tanto, es una copia local a cada hilo. Esto es algo hack en hacer variable de instancia en un método para ser accedido como un variable local. Como usted sabe método variable local es solo disponible para el hilo, una diferencia es; las variables locales del método no disponible para el hilo una vez que la ejecución del método ha terminado donde como mutable el objeto compartido con threadlocal estará disponible en varios métodos hasta que lo limpiemos.

Por Definición:

La clase ThreadLocal en Java le permite crear variables que pueden solo ser leído y escrito por el mismo hilo. Por lo tanto, incluso si dos hilos están ejecutando el mismo código, y el código tiene una referencia a un Variable ThreadLocal, entonces los dos hilos no pueden ver el uno del otro ThreadLocal variables.

Cada Thread en java contiene ThreadLocalMap en él.
Donde

Key = One ThreadLocal object shared across threads.
value = Mutable object which has to be used synchronously, this will be instantiated for each thread.

Lograr el ThreadLocal:

Ahora cree una clase wrapper para ThreadLocal que va a contener el objeto mutable como a continuación (con o sin initialValue()).
Ahora getter y setter de esta envoltura funcionarán en la instancia threadlocal en lugar de objeto mutable.

Si getter() de threadlocal no encontró ningún valor con en el threadlocalmap de Thread; entonces invocará el initialValue() para obtener su copia privada con respecto al hilo.

class SimpleDateFormatInstancePerThread {

    private static final ThreadLocal<SimpleDateFormat> dateFormatHolder = new ThreadLocal<SimpleDateFormat>() {

        @Override
        protected SimpleDateFormat initialValue() {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd") {
                UUID id = UUID.randomUUID();
                @Override
                public String toString() {
                    return id.toString();
                };
            };
            System.out.println("Creating SimpleDateFormat instance " + dateFormat +" for Thread : " + Thread.currentThread().getName());
            return dateFormat;
        }
    };

    /*
     * Every time there is a call for DateFormat, ThreadLocal will return calling
     * Thread's copy of SimpleDateFormat
     */
    public static DateFormat getDateFormatter() {
        return dateFormatHolder.get();
    }

    public static void cleanup() {
        dateFormatHolder.remove();
    }
}

Ahora wrapper.getDateFormatter() llamará a threadlocal.get() y eso comprobará que currentThread.threadLocalMap contiene esta instancia (threadlocal).
En caso afirmativo, devuelva el valor (SimpleDateFormat) para la instancia threadlocal correspondiente
de lo contrario, agregue el mapa con esta instancia threadlocal, initialValue().

Con esto se logra la seguridad del hilo en esta clase mutable; por cada hilo está trabajando con su propia instancia mutable pero con la misma instancia ThreadLocal. Significa que todo el subproceso compartirá la misma instancia ThreadLocal como clave, pero una instancia SimpleDateFormat diferente como valor.

Https://github.com/skanagavelu/yt.tech/blob/master/src/ThreadLocalTest.java

 3
Author: Kanagavelu Sugumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-07 05:29:06

¿Cuándo?

Cuando un objeto no es seguro para subprocesos, en lugar de sincronización que dificulta la escalabilidad, asigne un objeto a cada subproceso y manténgalo en el ámbito del subproceso, que es ThreadLocal. Uno de los objetos más utilizados pero no seguros para subprocesos son database Connection y JMSConnection.

¿Cómo ?

Un ejemplo es que Spring framework usa ThreadLocal en gran medida para administrar transacciones entre bastidores al mantener estos objetos de conexión en variables ThreadLocal. De alto nivel, cuando se inicia una transacción, obtiene la conexión ( y desactiva la confirmación automática ) y la mantiene en ThreadLocal. en otras llamadas a db, utiliza la misma conexión para comunicarse con db. Al final, toma la conexión de ThreadLocal y confirma (o reversa) la transacción y libera la conexión.

Creo que log4j también usa ThreadLocal para mantener MDC.

 3
Author: Limestone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-27 03:10:49

ThreadLocal es útil, cuando se quiere tener algún estado que no debe ser compartido entre diferentes hilos, pero debe ser accesible desde cada hilo durante toda su vida útil.

Como ejemplo, imagine una aplicación web, donde cada solicitud es servida por un hilo diferente. Imagine que para cada solicitud necesita una pieza de datos varias veces, lo cual es bastante costoso de calcular. Sin embargo, es posible que esos datos hayan cambiado para cada solicitud entrante, lo que significa que no puede usar un cache. Una solución simple y rápida a este problema sería tener una variable ThreadLocal que tenga acceso a estos datos, de modo que tenga que calcularlos solo una vez para cada solicitud. Por supuesto, este problema también se puede resolver sin el uso de ThreadLocal, pero lo ideé con fines ilustrativos.

Dicho esto, ten en cuenta que ThreadLocal s son esencialmente una forma de estado global. Como resultado, tiene muchas otras implicaciones y debe usarse solo después de considerar todas las otras soluciones posibles.

 2
Author: Dimos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-16 11:28:11

Las variables Thread-local a menudo se usan para evitar compartir diseños basados en singletons mutables o variables globales.

Se puede usar en escenarios como hacer una conexión JDBC separada para cada subproceso cuando no está utilizando un Grupo de conexiones.

private static ThreadLocal<Connection> connectionHolder
           = new ThreadLocal<Connection>() {
      public Connection initialValue() {
           return DriverManager.getConnection(DB_URL);
          }
     };

public static Connection getConnection() {
      return connectionHolder.get();
} 

Cuando llamas a getConnection, devolverá una conexión asociada a ese hilo.Lo mismo se puede hacer con otras propiedades como dateformat, contexto de transacción que no desea compartir entre subprocesos.

También podría haber utilizado variables locales para el mismo, pero estos recursos generalmente toman tiempo en la creación,por lo que no desea crearlos una y otra vez cada vez que realice alguna lógica de negocio con ellos. Sin embargo, los valores threadlocales se almacenan en el propio objeto thread y tan pronto como el thread se recolecta como basura, estos valores también desaparecen.

Este enlace explica muy bien el uso de ThreadLocal.

 2
Author: bpjoshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 07:58:44

Desde el lanzamiento de Java 8, hay una forma más declarativa de inicializar ThreadLocal:

ThreadLocal<Cipher> local = ThreadLocal.withInitial(() -> "init value");

Hasta el lanzamiento de Java 8, tenía que hacer lo siguiente:

ThreadLocal<String> local = new ThreadLocal<String>(){
    @Override
    protected String initialValue() {
        return "init value";
    }
};

Además, si el método de instanciación (constructor, método factory) de la clase que se usa para ThreadLocal no toma ningún parámetro, simplemente puede usar referencias de métodos (introducidas en Java 8):

class NotThreadSafe {
    // no parameters
    public NotThreadSafe(){}
}

ThreadLocal<NotThreadSafe> container = ThreadLocal.withInitial(NotThreadSafe::new);

Nota: La evaluación es perezosa ya que está pasando java.util.function.Supplier lambda que se evalúa solo cuando se llama ThreadLocal#get pero valor no fue evaluado previamente.

 2
Author: Andrii Abramov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-28 14:44:39

Almacenamiento en caché, en algún momento tiene que calcular el mismo valor mucho tiempo, por lo que al almacenar el último conjunto de entradas a un método y el resultado puede acelerar el código. Al usar el almacenamiento local de Subprocesos, evita tener que pensar en el bloqueo.

 0
Author: Ian Ringrose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-15 17:19:01

ThreadLocal es una funcionalidad especialmente aprovisionada por JVM para proporcionar un espacio de almacenamiento aislado solo para subprocesos. al igual que el valor de la variable de ámbito de instancia están vinculados a una instancia dada de una clase solamente. cada objeto tiene sus únicos valores y no pueden verse entre sí valor. así es el concepto de variables ThreadLocal, que son locales para el hilo en el sentido de instancias de objeto de otro hilo, excepto por el que lo creó, no puede verlo. Ver Aquí

import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;


public class ThreadId {
private static final AtomicInteger nextId = new AtomicInteger(1000);

// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId = ThreadLocal.withInitial(() -> nextId.getAndIncrement());


// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
    return threadId.get();
}

public static void main(String[] args) {

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

}
}
 0
Author: Ajay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-30 14:09:57

Threadlocal proporciona una manera muy fácil de lograr la reutilización de objetos con costo cero.

Tuve una situación en la que varios subprocesos estaban creando una imagen de caché mutable, en cada notificación de actualización.

Utilicé un Threadlocal en cada hilo, y luego cada hilo solo necesitaría restablecer la imagen antigua y luego actualizarla nuevamente desde la caché en cada notificación de actualización.

Los objetos reutilizables habituales de los grupos de objetos tienen un costo de seguridad de hilo asociado con ellos, mientras que esto el enfoque no tiene ninguno.

 0
Author: Dev Amitabh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-12 03:00:41

La clase ThreadLocal en Java le permite crear variables que solo pueden ser leídas y escritas por el mismo hilo. Por lo tanto, incluso si dos subprocesos están ejecutando el mismo código, y el código tiene una referencia a una variable ThreadLocal, entonces los dos subprocesos no pueden ver las variables ThreadLocal del otro.

Leer más

 0
Author: Pritesh Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-04 13:18:08