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

bookThreadlocal

ThreadLocal maakt het mogelijk om multithreading-gerelateerde mechanismen zoals synchronisatie te vermijden, omdat gegevens uit ThreadLocal alleen toegankelijk zijn binnen één enkele thread.

Stel je een bankapplicatie voor waarbij elke klant een eigen rekening heeft. Als meerdere klanten de applicatie gelijktijdig gebruiken, moeten hun rekeningen gescheiden blijven. Door gebruik te maken van ThreadLocal krijgt elke thread (klant) zijn eigen instantie van gegevens (rekening), waardoor wordt gegarandeerd dat deze niet interfereert met andere threads.

Hoe ThreadLocal te gebruiken

ThreadLocal biedt een get() methode en een set() methode, die voor zich spreken.

get() - haalt de waarde op uit de ThreadLocal variabele.

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

set() - stelt de waarde in voor de ThreadLocal variabele.

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

Laten we een programma maken om een eenvoudige variabele te vergelijken met ThreadLocal.

Elke thread heeft zijn eigen afzonderlijke threadLocalCounter, terwijl de waarde van sharedCounter wordt gewijzigd en gedeeld tussen alle threads. De uitvoer van het programma zal aantonen dat de waarden van threadLocalCounter uniek zijn voor elke thread, terwijl sharedCounter een gemeenschappelijk resultaat voor alle threads weergeeft, wat kan variëren afhankelijk van de volgorde waarin de threads worden uitgevoerd.

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(); } }

En nadat dit programma voor ons werkt, krijgen we het volgende resultaat:

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

Zoals je kunt zien, wordt de variabele sharedCounter verhoogd over verschillende threads, terwijl de variabele threadLocalCounter dezelfde waarde behoudt in elke thread, omdat elke thread zijn eigen threadLocalCounter-instantie heeft die onafhankelijk is van andere threads.

Zoals u wellicht heeft opgemerkt, bevat de code een statische methode ThreadLocal.withInitial() die een initiële waarde instelt voor de variabele wanneer deze wordt aangemaakt.

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

De remove() methode in de klasse ThreadLocal wordt gebruikt om de waarde te verwijderen die aan de huidige thread is gekoppeld.

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 resultaat van de uitvoering van het programma:

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

Het programma wijst een unieke waarde toe aan ThreadLocal voor elke thread en toont deze waarde voor en na het aanroepen van de methode remove(). Na het verwijderen van de waarde met remove(), retourneert ThreadLocal null bij volgende aanroepen van get().

Note
Opmerking

Gegevens die in ThreadLocal staan, worden niet automatisch verwijderd en moeten expliciet worden verwijderd!

Waarom Moet Ik een Waarde Vrijgeven?

Het vrijgeven van een waarde is essentieel om geheugenlekken te voorkomen. ThreadLocal houdt waarden gekoppeld aan threads in een speciale map die aan threads is gebonden. Als een waarde niet wordt verwijderd, blijft deze in de map staan, zelfs nadat het gebruik van de thread is voltooid, wat leidt tot onnodige objecten in het geheugen en uiteindelijk tot geheugenlekken.

1. Wat is het belangrijkste probleem dat wordt opgelost door het gebruik van ThreadLocal?

2. Wat is de initiële waarde van een ThreadLocal-variabele wanneer deze wordt aangemaakt met de withInitial()-methode?

3. Wat gebeurt er als u de remove()-methode niet aanroept voor een ThreadLocal-variabele in langlevende threads?

question mark

Wat is het belangrijkste probleem dat wordt opgelost door het gebruik van ThreadLocal?

Select the correct answer

question mark

Wat is de initiële waarde van een ThreadLocal-variabele wanneer deze wordt aangemaakt met de withInitial()-methode?

Select the correct answer

question mark

Wat gebeurt er als u de remove()-methode niet aanroept voor een ThreadLocal-variabele in langlevende threads?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 4. Hoofdstuk 4

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

Awesome!

Completion rate improved to 3.33

bookThreadlocal

Veeg om het menu te tonen

ThreadLocal maakt het mogelijk om multithreading-gerelateerde mechanismen zoals synchronisatie te vermijden, omdat gegevens uit ThreadLocal alleen toegankelijk zijn binnen één enkele thread.

Stel je een bankapplicatie voor waarbij elke klant een eigen rekening heeft. Als meerdere klanten de applicatie gelijktijdig gebruiken, moeten hun rekeningen gescheiden blijven. Door gebruik te maken van ThreadLocal krijgt elke thread (klant) zijn eigen instantie van gegevens (rekening), waardoor wordt gegarandeerd dat deze niet interfereert met andere threads.

Hoe ThreadLocal te gebruiken

ThreadLocal biedt een get() methode en een set() methode, die voor zich spreken.

get() - haalt de waarde op uit de ThreadLocal variabele.

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

set() - stelt de waarde in voor de ThreadLocal variabele.

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

Laten we een programma maken om een eenvoudige variabele te vergelijken met ThreadLocal.

Elke thread heeft zijn eigen afzonderlijke threadLocalCounter, terwijl de waarde van sharedCounter wordt gewijzigd en gedeeld tussen alle threads. De uitvoer van het programma zal aantonen dat de waarden van threadLocalCounter uniek zijn voor elke thread, terwijl sharedCounter een gemeenschappelijk resultaat voor alle threads weergeeft, wat kan variëren afhankelijk van de volgorde waarin de threads worden uitgevoerd.

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(); } }

En nadat dit programma voor ons werkt, krijgen we het volgende resultaat:

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

Zoals je kunt zien, wordt de variabele sharedCounter verhoogd over verschillende threads, terwijl de variabele threadLocalCounter dezelfde waarde behoudt in elke thread, omdat elke thread zijn eigen threadLocalCounter-instantie heeft die onafhankelijk is van andere threads.

Zoals u wellicht heeft opgemerkt, bevat de code een statische methode ThreadLocal.withInitial() die een initiële waarde instelt voor de variabele wanneer deze wordt aangemaakt.

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

De remove() methode in de klasse ThreadLocal wordt gebruikt om de waarde te verwijderen die aan de huidige thread is gekoppeld.

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 resultaat van de uitvoering van het programma:

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

Het programma wijst een unieke waarde toe aan ThreadLocal voor elke thread en toont deze waarde voor en na het aanroepen van de methode remove(). Na het verwijderen van de waarde met remove(), retourneert ThreadLocal null bij volgende aanroepen van get().

Note
Opmerking

Gegevens die in ThreadLocal staan, worden niet automatisch verwijderd en moeten expliciet worden verwijderd!

Waarom Moet Ik een Waarde Vrijgeven?

Het vrijgeven van een waarde is essentieel om geheugenlekken te voorkomen. ThreadLocal houdt waarden gekoppeld aan threads in een speciale map die aan threads is gebonden. Als een waarde niet wordt verwijderd, blijft deze in de map staan, zelfs nadat het gebruik van de thread is voltooid, wat leidt tot onnodige objecten in het geheugen en uiteindelijk tot geheugenlekken.

1. Wat is het belangrijkste probleem dat wordt opgelost door het gebruik van ThreadLocal?

2. Wat is de initiële waarde van een ThreadLocal-variabele wanneer deze wordt aangemaakt met de withInitial()-methode?

3. Wat gebeurt er als u de remove()-methode niet aanroept voor een ThreadLocal-variabele in langlevende threads?

question mark

Wat is het belangrijkste probleem dat wordt opgelost door het gebruik van ThreadLocal?

Select the correct answer

question mark

Wat is de initiële waarde van een ThreadLocal-variabele wanneer deze wordt aangemaakt met de withInitial()-methode?

Select the correct answer

question mark

Wat gebeurt er als u de remove()-methode niet aanroept voor een ThreadLocal-variabele in langlevende threads?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 4. Hoofdstuk 4
some-alt