Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Threadlocal | Bästa Praxis För Multitrådning
Quizzes & Challenges
Quizzes
Challenges
/
Multitrådning i Java

bookThreadlocal

ThreadLocal gör det möjligt att undvika mekanismer relaterade till multitrådning såsom synkronisering, eftersom data från ThreadLocal endast är tillgänglig inom en enskild tråd.

Föreställ dig en bankapplikation där varje kund har sitt eget konto. Om flera kunder använder applikationen samtidigt, ska deras konton förbli separata. Genom att använda ThreadLocal får varje tråd (kund) sin egen instans av data (konto), vilket säkerställer att den inte påverkar andra trådar.

Hur man använder ThreadLocal

ThreadLocal tillhandahåller en get() metod och en set() metod, vilka är självförklarande.

get() – hämtar värdet från ThreadLocal variabeln.

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

set() – sätter värdet till ThreadLocal variabeln.

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

Låt oss skapa ett program för att jämföra en enkel variabel med ThreadLocal.

Varje tråd kommer att ha sin egen unika threadLocalCounter, medan värdet på sharedCounter kommer att ändras och delas mellan alla trådar. Programmets utdata kommer att visa att värdena för threadLocalCounter är unika för varje tråd, medan sharedCounter kommer att återspegla ett gemensamt resultat för alla trådar, vilket kan variera beroende på i vilken ordning trådarna körs.

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

Och efter att detta program körs får vi följande resultat:

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

Som du kan se ökas variabeln sharedCounter mellan olika trådar, medan variabeln threadLocalCounter behåller samma värde i varje tråd, eftersom varje tråd har sin egen instans av threadLocalCounter som är oberoende av andra trådar.

Som du kanske har observerat innehåller koden en statisk metod ThreadLocal.withInitial() som anger ett initialvärde för variabeln när den skapas.

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

Metoden remove() i klassen ThreadLocal används för att ta bort värdet som är kopplat till den aktuella tråden.

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

Som ett resultat av programmets körning:

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 tilldelar ett unikt värde till ThreadLocal för varje tråd och visar detta värde före och efter att metoden remove() anropas. Efter att värdet har tagits bort med remove(), returnerar ThreadLocal null vid efterföljande anrop av get().

Note
Notering

Data som finns i ThreadLocal tas inte bort automatiskt och måste raderas explicit!

Varför behöver jag frigöra ett värde?

Att frigöra ett värde är avgörande för att förhindra minnesläckor. ThreadLocal behåller värden kopplade till trådar i en speciell karta som är bunden till trådarna. Om ett värde inte tas bort stannar det kvar i kartan även efter att trådens användning är klar, vilket leder till att onödiga objekt finns kvar i minnet och slutligen orsakar minnesläckor.

1. Vilket är det huvudsakliga problemet som användning av ThreadLocal löser?

2. Vad är startvärdet för en ThreadLocal-variabel när den skapas med metoden withInitial()?

3. Vad händer om du inte anropar metoden remove() för en ThreadLocal-variabel i långlivade trådar?

question mark

Vilket är det huvudsakliga problemet som användning av ThreadLocal löser?

Select the correct answer

question mark

Vad är startvärdet för en ThreadLocal-variabel när den skapas med metoden withInitial()?

Select the correct answer

question mark

Vad händer om du inte anropar metoden remove() för en ThreadLocal-variabel i långlivade trådar?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 4

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Awesome!

Completion rate improved to 3.33

bookThreadlocal

Svep för att visa menyn

ThreadLocal gör det möjligt att undvika mekanismer relaterade till multitrådning såsom synkronisering, eftersom data från ThreadLocal endast är tillgänglig inom en enskild tråd.

Föreställ dig en bankapplikation där varje kund har sitt eget konto. Om flera kunder använder applikationen samtidigt, ska deras konton förbli separata. Genom att använda ThreadLocal får varje tråd (kund) sin egen instans av data (konto), vilket säkerställer att den inte påverkar andra trådar.

Hur man använder ThreadLocal

ThreadLocal tillhandahåller en get() metod och en set() metod, vilka är självförklarande.

get() – hämtar värdet från ThreadLocal variabeln.

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

set() – sätter värdet till ThreadLocal variabeln.

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

Låt oss skapa ett program för att jämföra en enkel variabel med ThreadLocal.

Varje tråd kommer att ha sin egen unika threadLocalCounter, medan värdet på sharedCounter kommer att ändras och delas mellan alla trådar. Programmets utdata kommer att visa att värdena för threadLocalCounter är unika för varje tråd, medan sharedCounter kommer att återspegla ett gemensamt resultat för alla trådar, vilket kan variera beroende på i vilken ordning trådarna körs.

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

Och efter att detta program körs får vi följande resultat:

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

Som du kan se ökas variabeln sharedCounter mellan olika trådar, medan variabeln threadLocalCounter behåller samma värde i varje tråd, eftersom varje tråd har sin egen instans av threadLocalCounter som är oberoende av andra trådar.

Som du kanske har observerat innehåller koden en statisk metod ThreadLocal.withInitial() som anger ett initialvärde för variabeln när den skapas.

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

Metoden remove() i klassen ThreadLocal används för att ta bort värdet som är kopplat till den aktuella tråden.

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

Som ett resultat av programmets körning:

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 tilldelar ett unikt värde till ThreadLocal för varje tråd och visar detta värde före och efter att metoden remove() anropas. Efter att värdet har tagits bort med remove(), returnerar ThreadLocal null vid efterföljande anrop av get().

Note
Notering

Data som finns i ThreadLocal tas inte bort automatiskt och måste raderas explicit!

Varför behöver jag frigöra ett värde?

Att frigöra ett värde är avgörande för att förhindra minnesläckor. ThreadLocal behåller värden kopplade till trådar i en speciell karta som är bunden till trådarna. Om ett värde inte tas bort stannar det kvar i kartan även efter att trådens användning är klar, vilket leder till att onödiga objekt finns kvar i minnet och slutligen orsakar minnesläckor.

1. Vilket är det huvudsakliga problemet som användning av ThreadLocal löser?

2. Vad är startvärdet för en ThreadLocal-variabel när den skapas med metoden withInitial()?

3. Vad händer om du inte anropar metoden remove() för en ThreadLocal-variabel i långlivade trådar?

question mark

Vilket är det huvudsakliga problemet som användning av ThreadLocal löser?

Select the correct answer

question mark

Vad är startvärdet för en ThreadLocal-variabel när den skapas med metoden withInitial()?

Select the correct answer

question mark

Vad händer om du inte anropar metoden remove() för en ThreadLocal-variabel i långlivade trådar?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 4. Kapitel 4
some-alt