Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Threadlocal | Multithreading Best Practices
Multithreading in Java

bookThreadlocal

ThreadLocal ermöglicht das Vermeiden von mehrthreadbezogenen Mechanismen wie Synchronisation, da auf Daten aus ThreadLocal nur innerhalb eines einzelnen Threads zugegriffen werden kann.

Stellen Sie sich eine Bankanwendung vor, bei der jeder Kunde ein eigenes Konto besitzt. Wenn mehrere Kunden die Anwendung gleichzeitig nutzen, sollten ihre Konten getrennt bleiben. Durch die Verwendung von ThreadLocal erhält jeder Thread (Kunde) seine eigene Dateninstanz (Konto), wodurch sichergestellt wird, dass es keine Beeinflussung durch andere Threads gibt.

Verwendung von ThreadLocal

ThreadLocal stellt eine get() Methode und eine set() Methode bereit, deren Funktionsweise selbsterklärend ist.

get() – ruft den Wert aus der ThreadLocal-Variable ab.

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();

set() – setzt den Wert für die ThreadLocal-Variable.

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);

Erstellung eines Programms zum Vergleich einer einfachen Variablen mit ThreadLocal.

Jeder Thread besitzt seinen eigenen, separaten threadLocalCounter, während der Wert von sharedCounter verändert und unter allen Threads geteilt wird. Die Programmausgabe zeigt, dass die Werte von threadLocalCounter für jeden Thread einzigartig sind, während sharedCounter ein gemeinsames Ergebnis für alle Threads widerspiegelt, das je nach Ausführungsreihenfolge der Threads variieren kann.

ThreadLocalComparison.java

ThreadLocalComparison.java

CounterTask.java

CounterTask.java

copy
12345678910111213141516
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 ausgeführt wurde, erhalten wir folgendes Ergebnis:

Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1

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, von anderen Threads unabhängige threadLocalCounter-Instanz besitzt.

Wie Sie vielleicht bemerkt haben, enthält der Code eine statische Methode ThreadLocal.withInitial(), die einen Anfangswert für die Variable beim Erstellen festlegt.

ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);

Die Methode remove() in der Klasse ThreadLocal wird verwendet, um den Wert zu entfernen, der dem aktuellen Thread zugeordnet ist.

ThreadLocalTask.java

ThreadLocalTask.java

ThreadLocalRemoveExample.java

ThreadLocalRemoveExample.java

copy
123456789101112131415161718192021
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:

Thread-0 - ThreadLocal Value before removal: Thread-0 Value
Thread-0 - ThreadLocal Value after removal: null
Thread-1 - ThreadLocal Value before removal: Thread-1 Value
Thread-1 - ThreadLocal Value after removal: null

Das Programm weist jedem Thread einen eindeutigen Wert in 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.

Note
Hinweis

Daten, die sich in ThreadLocal befinden, werden nicht automatisch gelöscht und müssen explizit entfernt werden!

Warum muss ein Wert freigegeben werden?

Das Freigeben eines Wertes ist entscheidend, um Speicherlecks zu verhindern. ThreadLocal speichert Werte, die mit Threads in einer speziellen Map verknüpft sind. Wird ein Wert nicht entfernt, bleibt er in der Map, selbst nachdem der Thread nicht mehr verwendet wird. Dies führt dazu, dass unnötige Objekte im Speicher verbleiben und letztlich zu Speicherlecks führen.

1. Welches Hauptproblem wird durch die Verwendung von ThreadLocal gelöst?

2. Welchen Anfangswert hat eine ThreadLocal-Variable, wenn sie mit der Methode withInitial() erstellt wird?

3. Was passiert, wenn Sie die Methode remove() für eine ThreadLocal-Variable in langlebigen Threads nicht aufrufen?

question mark

Welches Hauptproblem wird durch die Verwendung von ThreadLocal gelöst?

Select the correct answer

question mark

Welchen Anfangswert hat eine ThreadLocal-Variable, wenn sie mit der Methode withInitial() erstellt wird?

Select the correct answer

question mark

Was passiert, wenn Sie die Methode remove() für eine ThreadLocal-Variable in langlebigen Threads nicht aufrufen?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 4. Kapitel 4

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Awesome!

Completion rate improved to 3.33

bookThreadlocal

Swipe um das Menü anzuzeigen

ThreadLocal ermöglicht das Vermeiden von mehrthreadbezogenen Mechanismen wie Synchronisation, da auf Daten aus ThreadLocal nur innerhalb eines einzelnen Threads zugegriffen werden kann.

Stellen Sie sich eine Bankanwendung vor, bei der jeder Kunde ein eigenes Konto besitzt. Wenn mehrere Kunden die Anwendung gleichzeitig nutzen, sollten ihre Konten getrennt bleiben. Durch die Verwendung von ThreadLocal erhält jeder Thread (Kunde) seine eigene Dateninstanz (Konto), wodurch sichergestellt wird, dass es keine Beeinflussung durch andere Threads gibt.

Verwendung von ThreadLocal

ThreadLocal stellt eine get() Methode und eine set() Methode bereit, deren Funktionsweise selbsterklärend ist.

get() – ruft den Wert aus der ThreadLocal-Variable ab.

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();

set() – setzt den Wert für die ThreadLocal-Variable.

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);

Erstellung eines Programms zum Vergleich einer einfachen Variablen mit ThreadLocal.

Jeder Thread besitzt seinen eigenen, separaten threadLocalCounter, während der Wert von sharedCounter verändert und unter allen Threads geteilt wird. Die Programmausgabe zeigt, dass die Werte von threadLocalCounter für jeden Thread einzigartig sind, während sharedCounter ein gemeinsames Ergebnis für alle Threads widerspiegelt, das je nach Ausführungsreihenfolge der Threads variieren kann.

ThreadLocalComparison.java

ThreadLocalComparison.java

CounterTask.java

CounterTask.java

copy
12345678910111213141516
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 ausgeführt wurde, erhalten wir folgendes Ergebnis:

Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1

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, von anderen Threads unabhängige threadLocalCounter-Instanz besitzt.

Wie Sie vielleicht bemerkt haben, enthält der Code eine statische Methode ThreadLocal.withInitial(), die einen Anfangswert für die Variable beim Erstellen festlegt.

ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);

Die Methode remove() in der Klasse ThreadLocal wird verwendet, um den Wert zu entfernen, der dem aktuellen Thread zugeordnet ist.

ThreadLocalTask.java

ThreadLocalTask.java

ThreadLocalRemoveExample.java

ThreadLocalRemoveExample.java

copy
123456789101112131415161718192021
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:

Thread-0 - ThreadLocal Value before removal: Thread-0 Value
Thread-0 - ThreadLocal Value after removal: null
Thread-1 - ThreadLocal Value before removal: Thread-1 Value
Thread-1 - ThreadLocal Value after removal: null

Das Programm weist jedem Thread einen eindeutigen Wert in 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.

Note
Hinweis

Daten, die sich in ThreadLocal befinden, werden nicht automatisch gelöscht und müssen explizit entfernt werden!

Warum muss ein Wert freigegeben werden?

Das Freigeben eines Wertes ist entscheidend, um Speicherlecks zu verhindern. ThreadLocal speichert Werte, die mit Threads in einer speziellen Map verknüpft sind. Wird ein Wert nicht entfernt, bleibt er in der Map, selbst nachdem der Thread nicht mehr verwendet wird. Dies führt dazu, dass unnötige Objekte im Speicher verbleiben und letztlich zu Speicherlecks führen.

1. Welches Hauptproblem wird durch die Verwendung von ThreadLocal gelöst?

2. Welchen Anfangswert hat eine ThreadLocal-Variable, wenn sie mit der Methode withInitial() erstellt wird?

3. Was passiert, wenn Sie die Methode remove() für eine ThreadLocal-Variable in langlebigen Threads nicht aufrufen?

question mark

Welches Hauptproblem wird durch die Verwendung von ThreadLocal gelöst?

Select the correct answer

question mark

Welchen Anfangswert hat eine ThreadLocal-Variable, wenn sie mit der Methode withInitial() erstellt wird?

Select the correct answer

question mark

Was passiert, wenn Sie die Methode remove() für eine ThreadLocal-Variable in langlebigen Threads nicht aufrufen?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 4. Kapitel 4
some-alt