Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Threadlocal | Mejores Prácticas de Multithreading
Multithreading en Java

bookThreadlocal

ThreadLocal permite evitar mecanismos relacionados con la multihilación como la sincronización, ya que los datos de ThreadLocal son accesibles únicamente dentro de un solo hilo.

Imagine una aplicación bancaria donde cada cliente tiene su propia cuenta. Si varios clientes utilizan la aplicación simultáneamente, sus cuentas deben permanecer separadas. Al utilizar ThreadLocal, cada hilo (cliente) obtiene su propia instancia de datos (cuenta), asegurando que no interfiera con otros hilos.

Cómo usar ThreadLocal

ThreadLocal proporciona un método get() y un método set(), cuyos nombres son autoexplicativos.

get() - recupera el valor de la variable ThreadLocal.

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();

set() - asigna el valor a la variable ThreadLocal.

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);

Creación de un programa para comparar una variable simple con ThreadLocal.

Cada hilo tendrá su propio threadLocalCounter distinto, mientras que el valor de sharedCounter será modificado y compartido entre todos los hilos. La salida del programa demostrará que los valores de threadLocalCounter son únicos para cada hilo, mientras que sharedCounter reflejará un resultado común para todos los hilos, el cual puede variar dependiendo del orden en que se ejecuten los hilos.

ThreadLocalComparison.java

ThreadLocalComparison.java

CounterTask.java

CounterTask.java

copy
12345678910111213141516
public class ThreadLocalComparison { public static void main(String[] args) { CounterTask counterTask = new CounterTask(); // Create threads for demonstrating the behavior Thread thread1 = new Thread(counterTask); Thread thread2 = new Thread(counterTask); Thread thread3 = new Thread(counterTask); // Start the threads thread1.start(); thread2.start(); thread3.start(); } }

Y después de que este programa se ejecute, obtenemos el siguiente resultado:

Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1

Como se puede observar, la variable sharedCounter se incrementa entre diferentes hilos, mientras que la variable threadLocalCounter mantiene el mismo valor en cada hilo, ya que cada hilo tiene su propia instancia de threadLocalCounter que es independiente de los demás hilos.

Como habrás observado, el código incluye un método estático ThreadLocal.withInitial() que establece un valor inicial para la variable cuando se crea.

ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);

El método remove() en la clase ThreadLocal se utiliza para eliminar el valor asociado con el hilo actual.

ThreadLocalTask.java

ThreadLocalTask.java

ThreadLocalRemoveExample.java

ThreadLocalRemoveExample.java

copy
123456789101112131415161718192021
class ThreadLocalTask implements Runnable { // Define a `ThreadLocal` variable with an initial value private static ThreadLocal<String> threadLocalValue = new ThreadLocal<>(); @Override public void run() { // Set a value in the `ThreadLocal` for this thread String threadName = Thread.currentThread().getName(); threadLocalValue.set(threadName + " Value"); // Print the current value System.out.println(threadName + " - ThreadLocal Value before removal: " + threadLocalValue.get()); // Remove the value associated with the current thread threadLocalValue.remove(); // Print the value after removal System.out.println(threadName + " - ThreadLocal Value after removal: " + threadLocalValue.get()); } }

Como resultado de la ejecución del programa:

Thread-0 - ThreadLocal Value before removal: Thread-0 Value
Thread-0 - ThreadLocal Value after removal: null
Thread-1 - ThreadLocal Value before removal: Thread-1 Value
Thread-1 - ThreadLocal Value after removal: null

El programa asigna un valor único a ThreadLocal para cada hilo y muestra este valor antes y después de que se invoque el método remove(). Después de eliminar el valor con remove(), ThreadLocal devuelve null en las llamadas posteriores a get().

Note
Nota

Los datos que están en ThreadLocal no se eliminan por sí mismos y deben ser eliminados explícitamente.

¿Por qué necesito liberar un valor?

Liberar un valor es fundamental para prevenir fugas de memoria. ThreadLocal mantiene los valores vinculados a los hilos en un mapa especial que está asociado a los hilos. Si un valor no se elimina, permanece en el mapa incluso después de que el uso del hilo haya finalizado, lo que provoca que objetos innecesarios permanezcan en memoria y, en última instancia, cause fugas de memoria.

1. ¿Cuál es el principal problema que resuelve el uso de ThreadLocal?

2. ¿Cuál es el valor inicial de una variable ThreadLocal cuando se crea usando el método withInitial()?

3. ¿Qué sucede si no se llama al método remove() para una variable ThreadLocal en hilos de larga duración?

question mark

¿Cuál es el principal problema que resuelve el uso de ThreadLocal?

Select the correct answer

question mark

¿Cuál es el valor inicial de una variable ThreadLocal cuando se crea usando el método withInitial()?

Select the correct answer

question mark

¿Qué sucede si no se llama al método remove() para una variable ThreadLocal en hilos de larga duración?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 4. Capítulo 4

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Awesome!

Completion rate improved to 3.33

bookThreadlocal

Desliza para mostrar el menú

ThreadLocal permite evitar mecanismos relacionados con la multihilación como la sincronización, ya que los datos de ThreadLocal son accesibles únicamente dentro de un solo hilo.

Imagine una aplicación bancaria donde cada cliente tiene su propia cuenta. Si varios clientes utilizan la aplicación simultáneamente, sus cuentas deben permanecer separadas. Al utilizar ThreadLocal, cada hilo (cliente) obtiene su propia instancia de datos (cuenta), asegurando que no interfiera con otros hilos.

Cómo usar ThreadLocal

ThreadLocal proporciona un método get() y un método set(), cuyos nombres son autoexplicativos.

get() - recupera el valor de la variable ThreadLocal.

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();

set() - asigna el valor a la variable ThreadLocal.

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);

Creación de un programa para comparar una variable simple con ThreadLocal.

Cada hilo tendrá su propio threadLocalCounter distinto, mientras que el valor de sharedCounter será modificado y compartido entre todos los hilos. La salida del programa demostrará que los valores de threadLocalCounter son únicos para cada hilo, mientras que sharedCounter reflejará un resultado común para todos los hilos, el cual puede variar dependiendo del orden en que se ejecuten los hilos.

ThreadLocalComparison.java

ThreadLocalComparison.java

CounterTask.java

CounterTask.java

copy
12345678910111213141516
public class ThreadLocalComparison { public static void main(String[] args) { CounterTask counterTask = new CounterTask(); // Create threads for demonstrating the behavior Thread thread1 = new Thread(counterTask); Thread thread2 = new Thread(counterTask); Thread thread3 = new Thread(counterTask); // Start the threads thread1.start(); thread2.start(); thread3.start(); } }

Y después de que este programa se ejecute, obtenemos el siguiente resultado:

Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1

Como se puede observar, la variable sharedCounter se incrementa entre diferentes hilos, mientras que la variable threadLocalCounter mantiene el mismo valor en cada hilo, ya que cada hilo tiene su propia instancia de threadLocalCounter que es independiente de los demás hilos.

Como habrás observado, el código incluye un método estático ThreadLocal.withInitial() que establece un valor inicial para la variable cuando se crea.

ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);

El método remove() en la clase ThreadLocal se utiliza para eliminar el valor asociado con el hilo actual.

ThreadLocalTask.java

ThreadLocalTask.java

ThreadLocalRemoveExample.java

ThreadLocalRemoveExample.java

copy
123456789101112131415161718192021
class ThreadLocalTask implements Runnable { // Define a `ThreadLocal` variable with an initial value private static ThreadLocal<String> threadLocalValue = new ThreadLocal<>(); @Override public void run() { // Set a value in the `ThreadLocal` for this thread String threadName = Thread.currentThread().getName(); threadLocalValue.set(threadName + " Value"); // Print the current value System.out.println(threadName + " - ThreadLocal Value before removal: " + threadLocalValue.get()); // Remove the value associated with the current thread threadLocalValue.remove(); // Print the value after removal System.out.println(threadName + " - ThreadLocal Value after removal: " + threadLocalValue.get()); } }

Como resultado de la ejecución del programa:

Thread-0 - ThreadLocal Value before removal: Thread-0 Value
Thread-0 - ThreadLocal Value after removal: null
Thread-1 - ThreadLocal Value before removal: Thread-1 Value
Thread-1 - ThreadLocal Value after removal: null

El programa asigna un valor único a ThreadLocal para cada hilo y muestra este valor antes y después de que se invoque el método remove(). Después de eliminar el valor con remove(), ThreadLocal devuelve null en las llamadas posteriores a get().

Note
Nota

Los datos que están en ThreadLocal no se eliminan por sí mismos y deben ser eliminados explícitamente.

¿Por qué necesito liberar un valor?

Liberar un valor es fundamental para prevenir fugas de memoria. ThreadLocal mantiene los valores vinculados a los hilos en un mapa especial que está asociado a los hilos. Si un valor no se elimina, permanece en el mapa incluso después de que el uso del hilo haya finalizado, lo que provoca que objetos innecesarios permanezcan en memoria y, en última instancia, cause fugas de memoria.

1. ¿Cuál es el principal problema que resuelve el uso de ThreadLocal?

2. ¿Cuál es el valor inicial de una variable ThreadLocal cuando se crea usando el método withInitial()?

3. ¿Qué sucede si no se llama al método remove() para una variable ThreadLocal en hilos de larga duración?

question mark

¿Cuál es el principal problema que resuelve el uso de ThreadLocal?

Select the correct answer

question mark

¿Cuál es el valor inicial de una variable ThreadLocal cuando se crea usando el método withInitial()?

Select the correct answer

question mark

¿Qué sucede si no se llama al método remove() para una variable ThreadLocal en hilos de larga duración?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 4. Capítulo 4
some-alt