 Threadlocal
Threadlocal
ThreadLocal permite evitar mecanismos relacionados à multithread, como sincronização, pois os dados de ThreadLocal são acessíveis apenas dentro de uma única thread.
Imagine uma aplicação bancária onde cada cliente possui sua própria conta. Se vários clientes estiverem usando a aplicação simultaneamente, as contas deles devem permanecer separadas. Utilizando ThreadLocal, cada thread (cliente) recebe sua própria instância de dados (conta), garantindo que não interfira em outras threads.
Como usar ThreadLocal
ThreadLocal fornece um método get() e um método set(), ambos autoexplicativos.
get() - recupera o valor da variável ThreadLocal.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();
set() - define o valor para a variável ThreadLocal.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);
Vamos criar um programa para comparar uma variável simples com ThreadLocal.
Cada thread terá seu próprio threadLocalCounter distinto, enquanto o valor de sharedCounter será alterado e compartilhado entre todas as threads. A saída do programa demonstrará que os valores de threadLocalCounter são únicos para cada thread, enquanto sharedCounter refletirá um resultado comum para todas as threads, que pode variar dependendo da ordem em que as threads são executadas.
ThreadLocalComparison.java
CounterTask.java
12345678910111213141516public 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(); } }
E após a execução deste programa, obtemos o seguinte resultado:
Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1
Como pode ser observado, a variável sharedCounter é incrementada entre diferentes threads, enquanto a variável threadLocalCounter mantém o mesmo valor em cada thread, pois cada thread possui sua própria instância de threadLocalCounter, que é independente das demais threads.
Como pode ser observado, o código inclui um método estático ThreadLocal.withInitial() que define um valor inicial para a variável quando ela é criada.
ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);
O método remove() na classe ThreadLocal é utilizado para remover o valor associado à thread atual.
ThreadLocalTask.java
ThreadLocalRemoveExample.java
123456789101112131415161718192021class 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 da execução do 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
O programa atribui um valor exclusivo ao ThreadLocal para cada thread e exibe esse valor antes e depois que o método remove() é invocado. Após remover o valor com remove(), o ThreadLocal retorna null em chamadas subsequentes ao get().
Os dados que estão em ThreadLocal não são excluídos automaticamente e devem ser excluídos explicitamente!
Por que preciso liberar um valor?
Liberar um valor é fundamental para evitar vazamentos de memória. O ThreadLocal mantém valores vinculados às threads em um mapa especial que é associado às threads. Se um valor não for removido, ele permanece no mapa mesmo após o uso da thread ser concluído, levando à permanência de objetos desnecessários na memória e, consequentemente, resultando em vazamentos de memória.
1. Qual é o principal problema que o uso de ThreadLocal resolve?
2. Qual é o valor inicial de uma variável ThreadLocal quando ela é criada usando o método withInitial()?
3. O que acontece se você não chamar o método remove() para uma variável ThreadLocal em threads de longa duração?
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
Awesome!
Completion rate improved to 3.33 Threadlocal
Threadlocal
Deslize para mostrar o menu
ThreadLocal permite evitar mecanismos relacionados à multithread, como sincronização, pois os dados de ThreadLocal são acessíveis apenas dentro de uma única thread.
Imagine uma aplicação bancária onde cada cliente possui sua própria conta. Se vários clientes estiverem usando a aplicação simultaneamente, as contas deles devem permanecer separadas. Utilizando ThreadLocal, cada thread (cliente) recebe sua própria instância de dados (conta), garantindo que não interfira em outras threads.
Como usar ThreadLocal
ThreadLocal fornece um método get() e um método set(), ambos autoexplicativos.
get() - recupera o valor da variável ThreadLocal.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();
set() - define o valor para a variável ThreadLocal.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);
Vamos criar um programa para comparar uma variável simples com ThreadLocal.
Cada thread terá seu próprio threadLocalCounter distinto, enquanto o valor de sharedCounter será alterado e compartilhado entre todas as threads. A saída do programa demonstrará que os valores de threadLocalCounter são únicos para cada thread, enquanto sharedCounter refletirá um resultado comum para todas as threads, que pode variar dependendo da ordem em que as threads são executadas.
ThreadLocalComparison.java
CounterTask.java
12345678910111213141516public 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(); } }
E após a execução deste programa, obtemos o seguinte resultado:
Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1
Como pode ser observado, a variável sharedCounter é incrementada entre diferentes threads, enquanto a variável threadLocalCounter mantém o mesmo valor em cada thread, pois cada thread possui sua própria instância de threadLocalCounter, que é independente das demais threads.
Como pode ser observado, o código inclui um método estático ThreadLocal.withInitial() que define um valor inicial para a variável quando ela é criada.
ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);
O método remove() na classe ThreadLocal é utilizado para remover o valor associado à thread atual.
ThreadLocalTask.java
ThreadLocalRemoveExample.java
123456789101112131415161718192021class 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 da execução do 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
O programa atribui um valor exclusivo ao ThreadLocal para cada thread e exibe esse valor antes e depois que o método remove() é invocado. Após remover o valor com remove(), o ThreadLocal retorna null em chamadas subsequentes ao get().
Os dados que estão em ThreadLocal não são excluídos automaticamente e devem ser excluídos explicitamente!
Por que preciso liberar um valor?
Liberar um valor é fundamental para evitar vazamentos de memória. O ThreadLocal mantém valores vinculados às threads em um mapa especial que é associado às threads. Se um valor não for removido, ele permanece no mapa mesmo após o uso da thread ser concluído, levando à permanência de objetos desnecessários na memória e, consequentemente, resultando em vazamentos de memória.
1. Qual é o principal problema que o uso de ThreadLocal resolve?
2. Qual é o valor inicial de uma variável ThreadLocal quando ela é criada usando o método withInitial()?
3. O que acontece se você não chamar o método remove() para uma variável ThreadLocal em threads de longa duração?
Obrigado pelo seu feedback!