Exemple ThreadLocal Java

Le ThreadLocal Java est utilisé pour créer des variables locales aux threads. Nous savons que tous les threads d’un objet partagent ses variables, ce qui rend la variable non sécurisée pour les threads. Nous pouvons utiliser la synchronisation pour assurer la sécurité des threads, mais si nous voulons éviter la synchronisation, nous pouvons utiliser les variables \texttt{ThreadLocal}.

ThreadLocal Java

Chaque thread a sa propre variable \texttt{ThreadLocal}, et ils peuvent utiliser ses méthodes \texttt{get()} et \texttt{set()} pour obtenir la valeur par défaut ou changer sa valeur localement au thread. Les instances ThreadLocal sont généralement des champs statiques privés dans les classes qui souhaitent associer un état à un thread.

Exemple ThreadLocal Java

Voici un petit exemple montrant l’utilisation de ThreadLocal dans un programme Java et prouvant que chaque thread a sa propre copie de la variable ThreadLocal. \texttt{ThreadLocalExample.java}

package com.journaldev.threads;

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

public class ThreadLocalExample implements Runnable{

    // SimpleDateFormat n'est pas thread-safe, donc donnez-en un à chaque 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();
        }
        // Le modèle du formateur est modifié ici par le thread, mais il ne se reflétera pas sur les autres threads
        formatter.set(new SimpleDateFormat());
        
        System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
    }

}

La sortie du programme exemple ThreadLocal Java ci-dessus est :

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

Comme vous pouvez le voir à partir de la sortie, Thread-0 a modifié la valeur du formateur, mais le formateur par défaut de Thread-2 reste identique à la valeur initialisée. Vous pouvez observer le même schéma pour les autres threads également. Mise à jour: La classe ThreadLocal a été étendue en Java 8 avec une nouvelle méthode withInitial() qui prend une interface fonctionnelle Supplier en argument. Ainsi, nous pouvons utiliser des expressions lambda pour créer facilement l’instance ThreadLocal. Par exemple, la variable ThreadLocal du formateur ci-dessus peut être définie en une seule ligne comme suit:

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

Si vous êtes nouveau aux fonctionnalités de Java 8, veuillez consulter Java 8 Features et Java 8 Functional Interfaces. C’est tout pour ThreadLocal dans la programmation Java. Référence: Documentation API

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