Contenu du cours
Multithreading en Java
Multithreading en Java
ThreadLocal
ThreadLocal
vous permet d'éviter les mécanismes liés au multithreading comme la synchronisation, car les données de ThreadLocal
sont accessibles uniquement au sein d'un seul thread.
Imaginez une application bancaire où chaque client a son propre compte. Si plusieurs clients utilisent l'application simultanément, leurs comptes doivent rester séparés. En utilisant ThreadLocal
, chaque thread (client) obtient sa propre instance de données (compte), garantissant qu'il ne n'interfère pas avec d'autres threads.
Comment utiliser ThreadLocal
ThreadLocal
fournit une méthode get()
et une méthode set()
, qui sont explicites.
get()
- récupère la valeur de la variable ThreadLocal
.
set()
- définir la valeur de la variable ThreadLocal
.
Créons un programme pour comparer une variable simple avec ThreadLocal
.
Chaque thread aura son propre threadLocalCounter
distinct, tandis que la valeur de sharedCounter
sera modifiée et partagée entre tous les threads. La sortie du programme démontrera que les valeurs de threadLocalCounter
sont uniques pour chaque thread, tandis que sharedCounter
reflétera un résultat commun pour tous les threads, qui peut varier en fonction de l'ordre d'exécution des threads.
ThreadLocalComparison
CounterTask
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(); } }
Et après que ce programme fonctionne pour nous, nous obtenons le résultat :
Comme vous pouvez le voir, la variable sharedCounter
est incrémentée à travers différents threads, tandis que la variable threadLocalCounter
maintient la même valeur dans chaque thread, car chaque thread a sa propre instance de threadLocalCounter
qui est indépendante des autres threads.
Comme vous avez pu l'observer, le code inclut une méthode statique ThreadLocal.withInitial()
qui définit une valeur initiale pour la variable lorsqu'elle est créée.
La méthode remove()
dans la classe ThreadLocal
est utilisée pour supprimer la valeur associée au thread actuel.
ThreadLocalTask
ThreadLocalRemoveExample
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()); } }
À la suite de l'exécution du programme :
Le programme assigne une valeur unique à ThreadLocal
pour chaque thread et affiche cette valeur avant et après que la méthode remove()
soit invoquée. Après avoir supprimé la valeur avec remove()
, ThreadLocal
retourne null lors des appels suivants à get()
.
Remarque
Les données qui sont dans
ThreadLocal
ne sont pas supprimées d'elles-mêmes et doivent être explicitement supprimées !
Pourquoi ai-je besoin de libérer une valeur ?
Libérer une valeur est crucial pour prévenir les fuites de mémoire. ThreadLocal
garde les valeurs liées aux threads dans une carte spéciale qui est liée aux threads. Si une valeur n'est pas supprimée, elle reste dans la carte même après que l'utilisation du thread est terminée, ce qui entraîne la présence d'objets inutiles en mémoire et conduit finalement à des fuites de mémoire.
1. Quel est le principal problème que l'utilisation de ThreadLocal résout ?
2. Quelle est la valeur initiale d'une variable ThreadLocal lorsqu'elle est créée en utilisant la méthode withInitial() ?
3. Que se passe-t-il si vous n'appelez pas la méthode remove() pour une variable ThreadLocal dans des threads de longue durée ?
Merci pour vos commentaires !