Esempio di ThreadLocal Java

Java ThreadLocal viene utilizzato per creare variabili locali al thread. Sappiamo che tutti i threads di un oggetto condividono le sue variabili, quindi la variabile non è sicura per il thread. Possiamo utilizzare la sincronizzazione per la sicurezza del thread ma se vogliamo evitare la sincronizzazione, possiamo utilizzare le variabili ThreadLocal.

Java ThreadLocal

Ogni thread ha la sua variabile ThreadLocal e possono utilizzare i suoi metodi get() e set() per ottenere il valore predefinito o cambiare il suo valore locale al Thread. Le istanze di ThreadLocal sono tipicamente campi privati statici nelle classi che desiderano associare uno stato a un thread.

Esempio di Java ThreadLocal

Ecco un piccolo esempio che mostra l’uso di ThreadLocal in un programma java e dimostra che ogni thread ha la sua copia della variabile ThreadLocal. EsempioThreadLocal.java

package com.journaldev.threads;

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

public class ThreadLocalExample implements Runnable{

    // SimpleDateFormat non è thread-safe, quindi ne diamo uno ad ogni thread
    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();
        }
        //il pattern del formatter è cambiato qui dal thread, ma non risulterà negli altri thread
        formatter.set(new SimpleDateFormat());
        
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
    }

}

L’output del programma di esempio java ThreadLocal sopra riportato è:

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

Come puoi vedere dall’output, Thread-0 ha cambiato il valore del formatter ma ancora il formatter predefinito del thread-2 è lo stesso del valore inizializzato. Puoi vedere lo stesso modello anche per gli altri thread. Aggiornamento: La classe ThreadLocal è estesa in Java 8 con un nuovo metodo withInitial() che prende come argomento l’interfaccia funzionale Supplier. Quindi possiamo usare le espressioni lambda per creare facilmente l’istanza ThreadLocal. Ad esempio, la variabile formatter ThreadLocal sopra può essere definita in una riga come segue:

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

Se sei nuovo alle funzionalità di Java 8, controlla Java 8 Features e Java 8 Functional Interfaces. Questo è tutto per ThreadLocal nella programmazione Java. Riferimento: API Doc

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