web-dev-qa-db-fra.com

Quand et comment utiliser une variable ThreadLocal?

Quand devrais-je utiliser une variable ThreadLocal?

Comment est-ce utilisé?

810
Sasha

Une utilisation possible (et courante) est lorsque vous avez un objet qui n'est pas thread-safe, mais que vous voulez éviter la synchronisation l'accès à cet objet (je vous regarde, SimpleDateFormat ). Au lieu de cela, donnez à chaque thread sa propre instance de l'objet.

Par exemple:

public class Foo
{
    // SimpleDateFormat is not thread-safe, so give one to each thread
    private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue()
        {
            return new SimpleDateFormat("yyyyMMdd HHmm");
        }
    };

    public String formatIt(Date date)
    {
        return formatter.get().format(date);
    }
}

Documentation .

803
overthink

Etant donné que ThreadLocal est une référence aux données d’une Thread donnée, vous pouvez vous retrouver avec des fuites de chargement de classes lorsque vous utilisez ThreadLocals dans des serveurs d’application utilisant des pools de threads. Vous devez faire très attention au nettoyage de ThreadLocals vous get() ou set() en utilisant la méthode ThreadLocal's remove().

Si vous ne nettoyez pas lorsque vous avez terminé, les références qu'il détient aux classes chargées dans le cadre d'une application Web déployée resteront dans le segment de mémoire permanent et ne seront jamais récupérées. Le redéploiement/annulation du déploiement de l'application Web ne nettoiera pas chaque référence de Thread aux classes de votre application Web, car la propriété Thread n'appartient pas à votre application Web. Chaque déploiement successif créera une nouvelle instance de la classe qui ne sera jamais récupérée.

Vous allez vous retrouver avec des exceptions de mémoire insuffisante à cause de Java.lang.OutOfMemoryError: PermGen space et après quelques recherches sur Google, vous augmenterez probablement simplement -XX:MaxPermSize au lieu de corriger le bogue.

Si vous rencontrez ces problèmes, vous pouvez déterminer le fil et la classe conservant ces références en utilisant Memory Analyzer d'Eclipse et/ou en suivant le guide de Frank Kieviet et suivi .

Mise à jour: Nouvelle découverte entrée de blog d’Alex Vasseur qui m’a aidé à repérer certains problèmes ThreadLocal que je rencontrais.

395
Phil M

De nombreux frameworks utilisent ThreadLocals pour maintenir un contexte lié au thread actuel. Par exemple, lorsque la transaction en cours est stockée dans un ThreadLocal, vous n'avez pas besoin de la transmettre en tant que paramètre à chaque appel de méthode, au cas où quelqu'un de la pile en aurait besoin. Les applications Web peuvent stocker des informations sur la demande et la session en cours dans un ThreadLocal, afin que l'application y ait facilement accès. Avec Guice, vous pouvez utiliser ThreadLocals lors de l'implémentation de custom scopes pour les objets injectés (les scopes par défaut de Guice servlet les utilisent aussi très probablement).

Les ThreadLocals sont une sorte de variables globales (bien qu'un peu moins pervers parce qu'elles sont limitées à un seul thread), vous devez donc être prudent lorsque vous les utilisez pour éviter les effets secondaires indésirables et les fuites de mémoire. Concevez vos API de manière à ce que les valeurs ThreadLocal soient toujours automatiquement effacées lorsqu'elles ne sont plus nécessaires, et qu'une utilisation incorrecte de l'API ne sera pas possible (par exemple like this ). ThreadLocals peut être utilisé pour rendre le code plus propre, et dans quelques rares cas, c'est le seul moyen de faire fonctionner quelque chose (mon projet actuel a deux cas de ce type; ils sont documentés ici sous "Champs statiques et variables globales") .

134
Esko Luontola

En Java, si vous avez une donnée qui peut varier d’un thread à l’autre, vous avez le choix de la transmettre à toutes les méthodes qui en ont besoin (ou peuvent en avoir besoin), ou d’associer la donnée au thread. Passer la donnée partout peut être faisable si toutes vos méthodes doivent déjà passer une variable "context" commune. 

Si ce n'est pas le cas, vous ne voudrez peut-être pas encombrer vos signatures de méthodes avec un paramètre supplémentaire. Dans un monde sans thread, vous pouvez résoudre le problème avec l'équivalent Java d'une variable globale. Dans un Word threadé, l'équivalent d'une variable globale est une variable locale de thread.

44
user100464

Il existe un très bon exemple dans le livre Java Concurrency in Practice. Où author ( Joshua Bloch ) explique comment le confinement de threads est l’un des moyens les plus simples d’atteindre la sécurité des threads et ThreadLocal est un moyen plus formel de maintenir le confinement de threads. Finalement, il explique également comment les gens peuvent en abuser en l’utilisant comme variable globale.

J'ai copié le texte du livre mentionné, mais le code 3.10 est manquant car il n'est pas très important de comprendre où ThreadLocal devrait être utilisé.

Les variables locales aux threads sont souvent utilisées pour empêcher le partage dans des conceptions basées sur des singletons mutables ou des variables globales. Par exemple, une application à un seul thread peut maintenir une connexion de base de données globale initialisée au démarrage pour éviter de devoir passer une connexion à chaque méthode. Etant donné que les connexions JDBC peuvent ne pas être thread-safe, une application multithread qui utilise une connexion globale sans coordination supplémentaire ne l'est pas non plus. En utilisant un ThreadLocal pour stocker la connexion JDBC, comme dans ConnectionHolder du Listing 3.10, chaque thread aura sa propre connexion.

ThreadLocal est largement utilisé dans la mise en œuvre de cadres d'application. Par exemple, les conteneurs J2EE associent un contexte de transaction à un thread en cours d'exécution pendant la durée d'un appel EJB. Ceci est facilement implémenté en utilisant un Thread-Local statique contenant le contexte de la transaction: lorsque le code d'infrastructure doit déterminer quelle transaction est en cours d'exécution, il extrait le contexte de la transaction à partir de ce ThreadLocal. Cela est pratique car cela réduit le besoin de transmettre des informations de contexte d'exécution à chaque méthode, mais couple tout code qui utilise ce mécanisme au framework.

Il est facile d’abuser de ThreadLocal en considérant sa propriété de confinement de threads comme une licence d’utilisation de variables globales ou comme un moyen de créer des arguments de méthode «masqués». Comme les variables globales, les variables locales aux unités d'exécution peuvent empêcher la possibilité de réutilisation et introduire des couplages cachés entre les classes. Elles doivent donc être utilisées avec précaution.

14
Rakesh Chauhan

Essentiellement, lorsque vous avez besoin d'une la valeur de la variable dépende du thread actuel} et qu'elle il n'est pas pratique pour vous d'associer la valeur au thread d'une autre manière} _ (par exemple, le sous-classement fil).

Un cas typique est celui où un autre framework a créé le fil dans lequel votre code est exécuté, par exemple. un conteneur de servlet, ou lorsqu'il est plus logique d'utiliser ThreadLocal car votre variable est alors "à son emplacement logique" (plutôt qu'une variable suspendue à une sous-classe Thread ou dans une autre mappe de hachage).

Sur mon site Web, j’ai un peu plus de une discussion et des exemples de quand utiliser ThreadLocal qui peuvent également être intéressants.

Certaines personnes préconisent l’utilisation de ThreadLocal comme moyen d’attacher un "ID de fil" à chaque fil dans certains algorithmes concurrents pour lesquels vous avez besoin d’un numéro de fil (voir par exemple Herlihy & Shavit). Dans de tels cas, vérifiez que vous obtenez réellement un avantage!

13
Neil Coffey

Le serveur Webapp peut conserver un pool de threads et une variable ThreadLocal doit être supprimée avant de répondre au client. Par conséquent, le thread actuel peut être réutilisé lors de la prochaine requête.

9
znlyj

La documentation le dit très bien: "chaque thread qui accède à [une variable locale à un thread] (via sa méthode get ou set) a sa propre copie de la variable initialisée indépendamment".

Vous en utilisez un lorsque chaque thread doit avoir sa propre copie de quelque chose. Par défaut, les données sont partagées entre les threads.

9
RichieHindle
  1. ThreadLocal en Java a été introduit sur JDK 1.2 mais a ensuite été généré dans JDK 1.5 pour introduire la sécurité de type sur la variable ThreadLocal.

  2. ThreadLocal peut être associé à la portée de Thread. Tout le code exécuté par Thread a accès aux variables ThreadLocal, mais deux threads ne peuvent pas voir les autres variables ThreadLocal.

  3. Chaque thread contient une copie exclusive de la variable ThreadLocal qui devient éligible à la récupération de place après la fin ou la fin du thread, normalement ou en raison d'une exception, étant donné que la variable ThreadLocal n'a aucune autre référence active.

  4. Les variables ThreadLocal en Java sont généralement des champs statiques privés dans Classes et conservent son état dans Thread.

En savoir plus: http://javarevisited.blogspot.com/2012/05/how-to-use-threadlocal-in-Java-benefits.html#ixzz2XltgbHTK

8
Abhijit Gaikwad

Deux cas d'utilisation où la variable threadlocal peut être utilisée - 
1- Lorsque nous devons associer un état à un fil (par exemple, un ID utilisateur ou un ID de transaction). Cela se produit généralement avec une application Web, chaque demande adressée à un servlet étant associée à un identifiant unique unique.

// This class will provide a thread local variable which
// will provide a unique ID for each thread
class ThreadId {
    // Atomic integer containing the next thread ID to be assigned
    private static final AtomicInteger nextId = new AtomicInteger(0);

    // Thread local variable containing each thread's ID
    private static final ThreadLocal<Integer> threadId =
        ThreadLocal.<Integer>withInitial(()-> {return nextId.getAndIncrement();});

    // Returns the current thread's unique ID, assigning it if necessary
    public static int get() {
        return threadId.get();
    }
}

Notez qu'ici la méthode withInitial est implémentée en utilisant l'expression lambda.
2- Un autre cas d'utilisation est lorsque nous voulons avoir une instance thread-safe et que nous ne voulons pas utiliser la synchronisation car le coût de performance associé à la synchronisation est supérieur. Un tel cas est lorsque SimpleDateFormat est utilisé. Puisque SimpleDateFormat n’est pas thread-safe, nous devons donc fournir un mécanisme pour le rendre thread-safe. 

public class ThreadLocalDemo1 implements Runnable {
    // threadlocal variable is created
    private static final ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue(){
            System.out.println("Initializing SimpleDateFormat for - " + Thread.currentThread().getName() );
            return new SimpleDateFormat("dd/MM/yyyy");
        }
    };

    public static void main(String[] args) {
        ThreadLocalDemo1 td = new ThreadLocalDemo1();
        // Two threads are created
        Thread t1 = new Thread(td, "Thread-1");
        Thread t2 = new Thread(td, "Thread-2");
        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        System.out.println("Thread run execution started for " + Thread.currentThread().getName());
        System.out.println("Date formatter pattern is  " + dateFormat.get().toPattern());
        System.out.println("Formatted date is " + dateFormat.get().format(new Date()));
    } 

}
7
infoj

Vous devez être très prudent avec le modèle ThreadLocal. Phil a mentionné certains inconvénients majeurs, mais l'un d'entre eux n'a pas été mentionné: il s'agit de s'assurer que le code qui définit le contexte ThreadLocal n'est pas "ré-entrant".

Des problèmes peuvent survenir lorsque le code qui définit les informations est exécuté une deuxième ou une troisième fois, car les informations sur votre thread peuvent commencer à muter lorsque vous ne vous y attendiez pas. Veillez donc à ce que les informations ThreadLocal n'aient pas été définies avant de les définir à nouveau.

4
Jeff Richley

Depuis Java 8, il existe plus de moyens déclaratifs pour initialiser ThreadLocal:

ThreadLocal<Cipher> local = ThreadLocal.withInitial(() -> "init value");

Jusqu'à la version Java 8, vous deviez:

ThreadLocal<String> local = new ThreadLocal<String>(){
    @Override
    protected String initialValue() {
        return "init value";
    }
};

De plus, si la méthode d'instanciation (constructeur, méthode d'usine) de la classe utilisée pour ThreadLocal ne prend aucun paramètre, vous pouvez simplement utiliser les références de méthode (introduites dans Java 8):

class NotThreadSafe {
    // no parameters
    public NotThreadSafe(){}
}

ThreadLocal<NotThreadSafe> container = ThreadLocal.withInitial(NotThreadSafe::new);

Remarque: L'évaluation est paresseuse puisque vous transmettez Java.util.function.Supplier lambda qui est évalué uniquement lorsque ThreadLocal#get est appelé mais que la valeur n'a pas été évaluée auparavant.

4
Andrii Abramov

quand?

Lorsqu'un objet n'est pas thread-safe, au lieu d'une synchronisation qui entrave l'évolutivité, attribuez un objet à chaque thread et conservez-y la portée du thread, à savoir ThreadLocal. L'un des objets les plus souvent utilisés, mais non thread-safe, sont Database Connection et JMSConnection. 

Comment ?

Spring, par exemple, utilise fréquemment ThreadLocal pour gérer les transactions en arrière-plan en conservant ces objets de connexion dans des variables ThreadLocal. À un niveau élevé, lorsqu'une transaction est démarrée, elle obtient la connexion (et désactive la validation automatique) et la conserve dans ThreadLocal. sur d'autres appels de base de données, il utilise la même connexion pour communiquer avec db. À la fin, il prend la connexion de ThreadLocal et valide (ou annule) la transaction et libère la connexion. 

Je pense que log4j utilise également ThreadLocal pour maintenir MDC.

4
Limestone

Comme mentionné par @unknown (Google), son utilisation est de définir une variable globale dans laquelle la valeur référencée peut être unique dans chaque thread. Ses utilisations impliquent généralement le stockage d'une sorte d'informations contextuelles liées au thread d'exécution en cours. 

Nous l'utilisons dans un environnement Java EE pour transmettre l'identité de l'utilisateur à des classes qui ne sont pas au courant de Java EE (nous n'avons pas accès à HttpSession ni à l'EJB SessionContext). De cette manière, le code, qui utilise l’identité pour des opérations basées sur la sécurité, peut accéder à l’identité de n’importe où, sans avoir à la transmettre explicitement à chaque appel de méthode.

Le cycle demande/réponse des opérations dans la plupart des appels Java EE facilite ce type d'utilisation, car il fournit des points d'entrée et de sortie bien définis pour définir et annuler la définition du ThreadLocal.

3
Robin

ThreadLocal est utile lorsque vous voulez avoir un état qui ne devrait pas être partagé entre différents threads, mais qui devrait être accessible à partir de chaque thread pendant toute sa durée de vie.

A titre d'exemple, imaginons une application Web, où chaque demande est servie par un thread différent. Imaginez que, pour chaque demande, vous ayez besoin d’un élément de données à plusieurs reprises, ce qui est assez coûteux à calculer. Toutefois, ces données peuvent avoir changé pour chaque demande entrante, ce qui signifie que vous ne pouvez pas utiliser un cache simple. Une solution simple et rapide à ce problème consisterait à avoir une variable ThreadLocal conservant l'accès à ces données, de sorte que vous ne deviez la calculer qu'une fois pour chaque demande. Bien sûr, ce problème peut également être résolu sans l'utilisation de ThreadLocal, mais je l'ai conçu à des fins d'illustration. 

Cela dit, gardez à l’esprit que les ThreadLocals sont essentiellement une forme d’état global. En conséquence, cela a de nombreuses autres implications et ne devrait être utilisé qu'après avoir considéré toutes les autres solutions possibles. 

3
Dimos

Rien de vraiment nouveau ici, mais j'ai découvert aujourd'hui que ThreadLocal est très utile pour utiliser la validation de bean dans une application Web. Les messages de validation sont localisés, mais utilisent par défaut Locale.getDefault(). Vous pouvez configurer la Validator avec une MessageInterpolator différente, mais vous ne pouvez pas spécifier la Locale lorsque vous appelez validate. Vous pouvez donc créer un ThreadLocal<Locale> statique (ou, mieux encore, un conteneur général contenant d’autres éléments dont vous aurez peut-être besoin d'être ThreadLocal, puis laisser votre MessageInterpolator personnalisé choisir la Locale. La prochaine étape consiste à écrire une ServletFilter qui utilise une valeur de session ou request.getLocale() pour sélectionner les paramètres régionaux et les stocker dans votre référence ThreadLocal.

3
Colselaw

ThreadLocal assurera l'accès à l'objet mutable par le multiple les threads dans la méthode non synchronisée sont synchronisés, ce qui signifie rendre l'objet mutable doit être immuable dans la méthode. 

Ce est obtenu en donnant une nouvelle instance d'objet mutable pour chaque thread essayez d'y accéder. Donc, il est une copie locale à chaque thread. Ça me ressemble tellement bidouillez pour créer une variable d'instance dans une méthode accessible, comme un variable locale. Comme vous le savez, la variable locale de la méthode est uniquement disponible pour le fil, une différence est; méthode variables locales ne sera pas disponible pour le thread une fois que l'exécution de la méthode est terminée là où est mutable L'objet partagé avec threadlocal sera disponible sur plusieurs méthodes jusqu'à ce que nous nettoyons.

Par définition:

La classe ThreadLocal en Java vous permet de créer des variables qui peuvent seulement être lu et écrit par le même fil. Ainsi, même si deux threads exécutent le même code, et le code a une référence à un Variable ThreadLocal, les deux threads ne peuvent pas se voir. Variables ThreadLocal.

Chaque Thread en Java contient ThreadLocalMap
Où 

Key = One ThreadLocal object shared across threads.
value = Mutable object which has to be used synchronously, this will be instantiated for each thread.

Atteindre le ThreadLocal: 

Créez maintenant une classe wrapper pour ThreadLocal qui contiendra l’objet mutable comme ci-dessous (avec ou sans initialValue()). 
Maintenant, le getter et le setter de ce wrapper fonctionneront sur une instance threadlocal au lieu d'un objet mutable.

Si getter () de threadlocal n'a trouvé aucune valeur dans la threadlocalmap du Thread; il invoquera ensuite initialValue () pour obtenir sa copie privée par rapport au thread.

class SimpleDateFormatInstancePerThread {

    private static final ThreadLocal<SimpleDateFormat> dateFormatHolder = new ThreadLocal<SimpleDateFormat>() {

        @Override
        protected SimpleDateFormat initialValue() {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd") {
                UUID id = UUID.randomUUID();
                @Override
                public String toString() {
                    return id.toString();
                };
            };
            System.out.println("Creating SimpleDateFormat instance " + dateFormat +" for Thread : " + Thread.currentThread().getName());
            return dateFormat;
        }
    };

    /*
     * Every time there is a call for DateFormat, ThreadLocal will return calling
     * Thread's copy of SimpleDateFormat
     */
    public static DateFormat getDateFormatter() {
        return dateFormatHolder.get();
    }

    public static void cleanup() {
        dateFormatHolder.remove();
    }
}

Maintenant, wrapper.getDateFormatter() appellera threadlocal.get() et vérifiera que le currentThread.threadLocalMap contient this (threadlocal) instance.
Si oui, renvoyer la valeur (SimpleDateFormat) pour l'instance threadlocal correspondante 
else ajouter la carte avec cette instance locale, initialValue (). 

Ici, la sécurité des fils est atteinte sur cette classe mutable; par chaque thread travaille avec sa propre instance mutable mais avec la même instance ThreadLocal. Tous les threads partageront la même instance ThreadLocal en tant que clé, mais une instance SimpleDateFormat différente en tant que valeur.

https://github.com/skanagavelu/yt.tech/blob/master/src/ThreadLocalTest.Java

3
Kanagavelu Sugumar

Les variables locales aux threads sont souvent utilisées pour empêcher le partage dans des conceptions basées sur des singletons mutables ou des variables globales

Il peut être utilisé dans des scénarios tels que l'établissement d'une connexion JDBC distincte pour chaque thread lorsque vous n'utilisez pas de pool de connexions.

private static ThreadLocal<Connection> connectionHolder
           = new ThreadLocal<Connection>() {
      public Connection initialValue() {
           return DriverManager.getConnection(DB_URL);
          }
     };

public static Connection getConnection() {
      return connectionHolder.get();
} 

Lorsque vous appelez getConnection, il renvoie une connexion associée à ce thread. Vous pouvez également faire de même avec d'autres propriétés telles que dateformat, contexte de transaction que vous ne souhaitez pas partager entre les threads. 

Vous auriez peut-être également utilisé des variables locales pour la même chose, mais ces ressources prennent généralement du temps lors de la création. Vous ne souhaitez donc pas les créer encore et encore chaque fois que vous exécutez une logique métier avec elles. Toutefois, les valeurs ThreadLocal sont stockées dans l'objet thread lui-même et dès que le thread est collecté, ces valeurs ont également disparu.

Ce link explique très bien l’utilisation de ThreadLocal.

2
bpjoshi

[Pour référence] ThreadLocal ne peut pas résoudre les problèmes de mise à jour d'objet partagé. Il est recommandé d'utiliser un objet staticThreadLocal qui est partagé par toutes les opérations du même thread. La méthode remove () doit être implémentée par les variables ThreadLocal, en particulier lors de l'utilisation de pools de threads dans lesquels les threads sont souvent réutilisés. Sinon, cela pourrait affecter la logique métier et générer des problèmes inattendus, tels que des fuites de mémoire.

1
Young

ThreadLocal est une fonctionnalité spécialement configurée par JVM pour fournir un espace de stockage isolé aux threads uniquement. comme la valeur d'instance, les variables couvertes ne sont liées qu'à une instance donnée d'une classe. chaque objet a ses seules valeurs et ils ne peuvent pas se voir. il en va de même pour le concept de variables ThreadLocal, elles sont locales pour le fil au sens des instances d'objet, à l'exception de celui qui l'a créé, ne le voit pas. Vois ici

import Java.util.concurrent.atomic.AtomicInteger;
import Java.util.stream.IntStream;


public class ThreadId {
private static final AtomicInteger nextId = new AtomicInteger(1000);

// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId = ThreadLocal.withInitial(() -> nextId.getAndIncrement());


// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
    return threadId.get();
}

public static void main(String[] args) {

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

    new Thread(() -> IntStream.range(1, 3).forEach(i -> {
        System.out.println(Thread.currentThread().getName() + " >> " + new ThreadId().get());
    })).start();

}
}
0
Ajay

En cache, vous devez parfois calculer la même valeur plusieurs fois. Ainsi, en stockant le dernier jeu d'entrées d'une méthode et le résultat, vous pouvez accélérer le code. En utilisant Thread Local Storage, vous évitez de penser au verrouillage.

0
Ian Ringrose

Il existe 3 scénarios pour utiliser un assistant de classe comme SimpleDateFormat dans un code multithread, dont le meilleur est use ThreadLocal

Scénarios

1- Utiliser comme objet de partage à l'aide de verrouiller ou synchroniser le mécanisme qui rend l'application lente

2- Utilisation en tant que objet local à l'intérieur d'une méthode 

Dans ce scénario, si nous avons 4 threads chacun appelle une méthode 1000 fois, nous avons
4000 SimpleDateFormat objet créé et attend que GC les efface 

3- Utilisation de ThreadLocal 

si nous avons 4 threads et que nous donnons à chaque thread une instance SimpleDateFormat} _
nous avons donc 4 threads _, 4 objets de SimpleDateFormat.

Aucun mécanisme de verrouillage ni création ou destruction d’objet n’est nécessaire. (Bonne complexité temporelle et spatiale)

0
mohsen.nour

Threadlocal offre un moyen très simple de réutiliser les objets sans coût supplémentaire.

J'ai eu une situation où plusieurs threads créaient une image de cache mutable, sur chaque notification de mise à jour.

J'ai utilisé un Threadlocal sur chaque thread, puis chaque thread aurait simplement besoin de réinitialiser l'ancienne image, puis de la mettre à jour à nouveau à partir du cache à chaque notification de mise à jour.

Les objets réutilisables habituels des pools d'objets sont associés à des coûts de sécurité des threads, alors que cette approche n'en a aucun. 

0
Dev Amitabh

La classe ThreadLocal en Java vous permet de créer des variables qui ne peuvent être lues et écrites que par le même thread. Ainsi, même si deux threads exécutent le même code et que le code fait référence à une variable ThreadLocal, ils ne peuvent pas voir les variables ThreadLocal l'un de l'autre.

Lire la suite

0
Pritesh Patel