Kursinhalt
Multithreading in Java
Multithreading in Java
ThreadLocal
ThreadLocal
ermöglicht es Ihnen, mechanismen im Zusammenhang mit Multithreading wie Synchronisation zu vermeiden, da Daten von ThreadLocal
nur innerhalb eines einzelnen Threads zugänglich sind.
Stellen Sie sich eine Bankanwendung vor, bei der jeder Kunde ein eigenes Konto hat. Wenn mehrere Kunden die Anwendung gleichzeitig nutzen, sollten ihre Konten getrennt bleiben. Durch die Verwendung von ThreadLocal
erhält jeder Thread (Kunde) seine eigene Instanz von Daten (Konto), was sicherstellt, dass er nicht mit anderen Threads interferiert.
Wie man ThreadLocal verwendet
ThreadLocal
bietet eine get()
Methode und eine set()
Methode, die selbsterklärend sind.
get()
- ruft den Wert aus der ThreadLocal
Variable ab.
set()
- den Wert auf die ThreadLocal
Variable setzen.
Lassen Sie uns ein Programm erstellen, um eine einfache Variable mit ThreadLocal
zu vergleichen.
Jeder Thread wird seinen eigenen, eindeutigen threadLocalCounter
haben, während der sharedCounter
-Wert geändert und unter allen Threads geteilt wird. Die Ausgabe des Programms wird zeigen, dass threadLocalCounter
-Werte für jeden Thread einzigartig sind, während sharedCounter
ein gemeinsames Ergebnis für alle Threads widerspiegelt, das je nach Reihenfolge der Ausführung der Threads variieren kann.
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(); } }
Und nachdem dieses Programm für uns funktioniert, erhalten wir das Ergebnis:
Wie Sie sehen können, wird die Variable sharedCounter
über verschiedene Threads hinweg inkrementiert, während die Variable threadLocalCounter
in jedem Thread denselben Wert beibehält, da jeder Thread seine eigene threadLocalCounter
-Instanz hat, die unabhängig von anderen Threads ist.
Wie Sie vielleicht beobachtet haben, enthält der Code eine statische Methode ThreadLocal.withInitial()
, die einen Anfangswert für die Variable festlegt, wenn sie erstellt wird.
Die remove()
Methode in der ThreadLocal
Klasse wird verwendet, um den Wert zu entfernen, der mit dem aktuellen Thread verknüpft ist.
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()); } }
Als Ergebnis der Programmausführung:
Das Programm weist jedem Thread einen eindeutigen Wert zu ThreadLocal
zu und zeigt diesen Wert vor und nach dem Aufruf der Methode remove()
an. Nach dem Entfernen des Wertes mit remove()
gibt ThreadLocal
bei nachfolgenden Aufrufen von get()
null zurück.
Hinweis
Daten, die in
ThreadLocal
sind, werden nicht selbst gelöscht und müssen explizit gelöscht werden!
Warum muss ich einen Wert freigeben?
Das Freigeben eines Wertes ist entscheidend, um Speicherlecks zu verhindern. ThreadLocal
hält Werte, die mit Threads in einer speziellen Karte verknüpft sind, die an Threads gebunden ist. Wenn ein Wert nicht entfernt wird, bleibt er in der Karte, selbst nachdem die Nutzung des Threads abgeschlossen ist, was dazu führt, dass unnötige Objekte im Speicher verbleiben und letztendlich zu Speicherlecks führt.
1. Welches Hauptproblem löst die Verwendung von ThreadLocal?
2. Was ist der Anfangswert einer ThreadLocal-Variablen, wenn sie mit der Methode withInitial() erstellt wird?
3. Was passiert, wenn Sie die remove()-Methode für eine ThreadLocal-Variable in langlebigen Threads nicht aufrufen?
Danke für Ihr Feedback!