Threadlocal
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
CounterTask.java
12345678910111213141516public 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
ThreadLocalRemoveExample.java
123456789101112131415161718192021class 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().
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?
Bedankt voor je feedback!
Vraag AI
Vraag AI
Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.
Awesome!
Completion rate improved to 3.33
Threadlocal
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
CounterTask.java
12345678910111213141516public 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
ThreadLocalRemoveExample.java
123456789101112131415161718192021class 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().
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?
Bedankt voor je feedback!