Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Threadlocal | Migliori Pratiche per il Multithreading
Multithreading in Java

bookThreadlocal

ThreadLocal consente di evitare meccanismi legati al multithreading come la sincronizzazione, poiché i dati di ThreadLocal sono accessibili solo all'interno di un singolo thread.

Si immagini un'applicazione bancaria in cui ogni cliente possiede il proprio conto. Se più clienti utilizzano l'applicazione contemporaneamente, i loro conti devono rimanere separati. Utilizzando ThreadLocal, ogni thread (cliente) ottiene la propria istanza di dati (conto), garantendo che non vi sia interferenza con altri thread.

Come utilizzare ThreadLocal

ThreadLocal fornisce un metodo get() e un metodo set(), i cui nomi sono autoesplicativi.

get() - recupera il valore dalla variabile ThreadLocal.

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

set() - imposta il valore nella variabile ThreadLocal.

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

Creazione di un programma per confrontare una variabile semplice con ThreadLocal.

Ogni thread avrà il proprio threadLocalCounter distinto, mentre il valore di sharedCounter verrà modificato e condiviso tra tutti i thread. L'output del programma mostrerà che i valori di threadLocalCounter sono unici per ciascun thread, mentre sharedCounter rifletterà un risultato comune per tutti i thread, che potrebbe variare a seconda dell'ordine di esecuzione dei thread.

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(); } }

E dopo che questo programma viene eseguito, otteniamo il seguente risultato:

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

Come si può notare, la variabile sharedCounter viene incrementata tra thread diversi, mentre la variabile threadLocalCounter mantiene lo stesso valore in ogni thread, poiché ogni thread possiede la propria istanza di threadLocalCounter indipendente dagli altri thread.

Come avrai notato, il codice include un metodo statico ThreadLocal.withInitial() che imposta un valore iniziale per la variabile al momento della sua creazione.

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

Il metodo remove() nella classe ThreadLocal viene utilizzato per rimuovere il valore associato al thread corrente.

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()); } }

Come risultato dell'esecuzione del programma:

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

Il programma assegna un valore univoco a ThreadLocal per ciascun thread e mostra questo valore prima e dopo che il metodo remove() viene invocato. Dopo la rimozione del valore con remove(), ThreadLocal restituisce null alle chiamate successive a get().

Note
Nota

I dati presenti in ThreadLocal non vengono eliminati automaticamente e devono essere eliminati esplicitamente!

Perché è Necessario Liberare un Valore?

Liberare un valore è fondamentale per prevenire perdite di memoria. ThreadLocal mantiene i valori associati ai thread in una mappa speciale che è vincolata ai thread. Se un valore non viene rimosso, rimane nella mappa anche dopo che l'utilizzo del thread è terminato, portando alla permanenza di oggetti non necessari in memoria e causando infine perdite di memoria.

1. Qual è il principale problema che l'utilizzo di ThreadLocal risolve?

2. Qual è il valore iniziale di una variabile ThreadLocal quando viene creata utilizzando il metodo withInitial()?

3. Cosa succede se non si chiama il metodo remove() per una variabile ThreadLocal nei thread di lunga durata?

question mark

Qual è il principale problema che l'utilizzo di ThreadLocal risolve?

Select the correct answer

question mark

Qual è il valore iniziale di una variabile ThreadLocal quando viene creata utilizzando il metodo withInitial()?

Select the correct answer

question mark

Cosa succede se non si chiama il metodo remove() per una variabile ThreadLocal nei thread di lunga durata?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 4. Capitolo 4

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

Suggested prompts:

Can you explain more about how ThreadLocal prevents memory leaks?

What are some common use cases for ThreadLocal in real-world applications?

How does ThreadLocal differ from using synchronized blocks or other thread-safety mechanisms?

Awesome!

Completion rate improved to 3.33

bookThreadlocal

Scorri per mostrare il menu

ThreadLocal consente di evitare meccanismi legati al multithreading come la sincronizzazione, poiché i dati di ThreadLocal sono accessibili solo all'interno di un singolo thread.

Si immagini un'applicazione bancaria in cui ogni cliente possiede il proprio conto. Se più clienti utilizzano l'applicazione contemporaneamente, i loro conti devono rimanere separati. Utilizzando ThreadLocal, ogni thread (cliente) ottiene la propria istanza di dati (conto), garantendo che non vi sia interferenza con altri thread.

Come utilizzare ThreadLocal

ThreadLocal fornisce un metodo get() e un metodo set(), i cui nomi sono autoesplicativi.

get() - recupera il valore dalla variabile ThreadLocal.

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

set() - imposta il valore nella variabile ThreadLocal.

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

Creazione di un programma per confrontare una variabile semplice con ThreadLocal.

Ogni thread avrà il proprio threadLocalCounter distinto, mentre il valore di sharedCounter verrà modificato e condiviso tra tutti i thread. L'output del programma mostrerà che i valori di threadLocalCounter sono unici per ciascun thread, mentre sharedCounter rifletterà un risultato comune per tutti i thread, che potrebbe variare a seconda dell'ordine di esecuzione dei thread.

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(); } }

E dopo che questo programma viene eseguito, otteniamo il seguente risultato:

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

Come si può notare, la variabile sharedCounter viene incrementata tra thread diversi, mentre la variabile threadLocalCounter mantiene lo stesso valore in ogni thread, poiché ogni thread possiede la propria istanza di threadLocalCounter indipendente dagli altri thread.

Come avrai notato, il codice include un metodo statico ThreadLocal.withInitial() che imposta un valore iniziale per la variabile al momento della sua creazione.

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

Il metodo remove() nella classe ThreadLocal viene utilizzato per rimuovere il valore associato al thread corrente.

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()); } }

Come risultato dell'esecuzione del programma:

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

Il programma assegna un valore univoco a ThreadLocal per ciascun thread e mostra questo valore prima e dopo che il metodo remove() viene invocato. Dopo la rimozione del valore con remove(), ThreadLocal restituisce null alle chiamate successive a get().

Note
Nota

I dati presenti in ThreadLocal non vengono eliminati automaticamente e devono essere eliminati esplicitamente!

Perché è Necessario Liberare un Valore?

Liberare un valore è fondamentale per prevenire perdite di memoria. ThreadLocal mantiene i valori associati ai thread in una mappa speciale che è vincolata ai thread. Se un valore non viene rimosso, rimane nella mappa anche dopo che l'utilizzo del thread è terminato, portando alla permanenza di oggetti non necessari in memoria e causando infine perdite di memoria.

1. Qual è il principale problema che l'utilizzo di ThreadLocal risolve?

2. Qual è il valore iniziale di una variabile ThreadLocal quando viene creata utilizzando il metodo withInitial()?

3. Cosa succede se non si chiama il metodo remove() per una variabile ThreadLocal nei thread di lunga durata?

question mark

Qual è il principale problema che l'utilizzo di ThreadLocal risolve?

Select the correct answer

question mark

Qual è il valore iniziale di una variabile ThreadLocal quando viene creata utilizzando il metodo withInitial()?

Select the correct answer

question mark

Cosa succede se non si chiama il metodo remove() per una variabile ThreadLocal nei thread di lunga durata?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 4. Capitolo 4
some-alt