Threadlokal
ThreadLocal gør det muligt at undgå mekanismer relateret til multitrådning såsom synkronisering, da data fra ThreadLocal kun er tilgængelige inden for en enkelt tråd.
Forestil dig en bankapplikation, hvor hver kunde har sin egen konto. Hvis flere kunder bruger applikationen samtidigt, skal deres konti forblive adskilte. Ved at bruge ThreadLocal får hver tråd (kunde) sin egen instans af data (konto), hvilket sikrer, at den ikke forstyrrer andre tråde.
Sådan bruges ThreadLocal
ThreadLocal tilbyder en get() metode og en set() metode, som er selvforklarende.
get() - henter værdien fra ThreadLocal variablen.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();
set() - sætter værdien til ThreadLocal variablen.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);
Lad os oprette et program for at sammenligne en simpel variabel med ThreadLocal.
Hver tråd vil have sin egen unikke threadLocalCounter, mens værdien af sharedCounter vil blive ændret og delt mellem alle tråde. Programmets output vil demonstrere, at threadLocalCounter-værdier er unikke for hver tråd, mens sharedCounter vil afspejle et fælles resultat for alle tråde, hvilket kan variere afhængigt af rækkefølgen, trådene udføres i.
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(); } }
Og efter dette program kører for os, får vi følgende resultat:
Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1
Som det kan ses, bliver variablen sharedCounter forøget på tværs af forskellige tråde, mens variablen threadLocalCounter bevarer den samme værdi i hver tråd, fordi hver tråd har sin egen threadLocalCounter-instans, som er uafhængig af andre tråde.
Som du måske har bemærket, indeholder koden en statisk metode ThreadLocal.withInitial(), der angiver en initial værdi for variablen, når den oprettes.
ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);
Metoden remove() i klassen ThreadLocal bruges til at fjerne værdien, der er knyttet til den aktuelle tråd.
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()); } }
Som et resultat af programmets udførelse:
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
Programmet tildeler en unik værdi til ThreadLocal for hver tråd og viser denne værdi før og efter, at metoden remove() kaldes. Efter fjernelse af værdien med remove(), returnerer ThreadLocal null ved efterfølgende kald til get().
Data, der er i ThreadLocal, bliver ikke slettet af sig selv og skal eksplicit slettes!
Hvorfor skal jeg frigøre en værdi?
Frigørelse af en værdi er afgørende for at undgå hukommelseslækager. ThreadLocal opbevarer værdier, der er knyttet til tråde, i et særligt kort, som er bundet til tråde. Hvis en værdi ikke fjernes, forbliver den i kortet, selv efter trådens brug er afsluttet, hvilket fører til unødvendige objekter i hukommelsen og i sidste ende resulterer i hukommelseslækager.
1. Hvilket hovedproblem løser brugen af ThreadLocal?
2. Hvad er den initiale værdi af en ThreadLocal-variabel, når den oprettes med metoden withInitial()?
3. Hvad sker der, hvis du ikke kalder remove()-metoden for en ThreadLocal-variabel i langlivede tråde?
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat
Awesome!
Completion rate improved to 3.33
Threadlokal
Stryg for at vise menuen
ThreadLocal gør det muligt at undgå mekanismer relateret til multitrådning såsom synkronisering, da data fra ThreadLocal kun er tilgængelige inden for en enkelt tråd.
Forestil dig en bankapplikation, hvor hver kunde har sin egen konto. Hvis flere kunder bruger applikationen samtidigt, skal deres konti forblive adskilte. Ved at bruge ThreadLocal får hver tråd (kunde) sin egen instans af data (konto), hvilket sikrer, at den ikke forstyrrer andre tråde.
Sådan bruges ThreadLocal
ThreadLocal tilbyder en get() metode og en set() metode, som er selvforklarende.
get() - henter værdien fra ThreadLocal variablen.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();
set() - sætter værdien til ThreadLocal variablen.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);
Lad os oprette et program for at sammenligne en simpel variabel med ThreadLocal.
Hver tråd vil have sin egen unikke threadLocalCounter, mens værdien af sharedCounter vil blive ændret og delt mellem alle tråde. Programmets output vil demonstrere, at threadLocalCounter-værdier er unikke for hver tråd, mens sharedCounter vil afspejle et fælles resultat for alle tråde, hvilket kan variere afhængigt af rækkefølgen, trådene udføres i.
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(); } }
Og efter dette program kører for os, får vi følgende resultat:
Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1
Som det kan ses, bliver variablen sharedCounter forøget på tværs af forskellige tråde, mens variablen threadLocalCounter bevarer den samme værdi i hver tråd, fordi hver tråd har sin egen threadLocalCounter-instans, som er uafhængig af andre tråde.
Som du måske har bemærket, indeholder koden en statisk metode ThreadLocal.withInitial(), der angiver en initial værdi for variablen, når den oprettes.
ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);
Metoden remove() i klassen ThreadLocal bruges til at fjerne værdien, der er knyttet til den aktuelle tråd.
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()); } }
Som et resultat af programmets udførelse:
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
Programmet tildeler en unik værdi til ThreadLocal for hver tråd og viser denne værdi før og efter, at metoden remove() kaldes. Efter fjernelse af værdien med remove(), returnerer ThreadLocal null ved efterfølgende kald til get().
Data, der er i ThreadLocal, bliver ikke slettet af sig selv og skal eksplicit slettes!
Hvorfor skal jeg frigøre en værdi?
Frigørelse af en værdi er afgørende for at undgå hukommelseslækager. ThreadLocal opbevarer værdier, der er knyttet til tråde, i et særligt kort, som er bundet til tråde. Hvis en værdi ikke fjernes, forbliver den i kortet, selv efter trådens brug er afsluttet, hvilket fører til unødvendige objekter i hukommelsen og i sidste ende resulterer i hukommelseslækager.
1. Hvilket hovedproblem løser brugen af ThreadLocal?
2. Hvad er den initiale værdi af en ThreadLocal-variabel, når den oprettes med metoden withInitial()?
3. Hvad sker der, hvis du ikke kalder remove()-metoden for en ThreadLocal-variabel i langlivede tråde?
Tak for dine kommentarer!