ThreadLocal
ThreadLocal mahdollistaa monisäikeisyyteen liittyvien mekanismien kuten synkronoinnin välttämisen, sillä ThreadLocal-datan saa käyttöön vain yksittäisessä säikeessä.
Kuvittele pankkisovellus, jossa jokaisella asiakkaalla on oma tili. Jos useat asiakkaat käyttävät sovellusta samanaikaisesti, heidän tilinsä tulee pysyä erillään. Käyttämällä ThreadLocal:ia jokainen säie (asiakas) saa oman tietokappaleensa (tili), mikä varmistaa, että se ei vaikuta muiden säikeiden tietoihin.
ThreadLocalin käyttö
ThreadLocal tarjoaa get() metodin ja set() metodin, jotka ovat itsestään selviä.
get() – hakee arvon ThreadLocal muuttujasta.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();
set() – asettaa arvon ThreadLocal muuttujaan.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);
Luodaan ohjelma, jossa verrataan yksinkertaista muuttujaa ja ThreadLocal-muuttujaa.
Jokaisella säikeellä on oma erillinen threadLocalCounter, kun taas sharedCounter-arvoa muutetaan ja jaetaan kaikkien säikeiden kesken. Ohjelman tuloste osoittaa, että threadLocalCounter-arvot ovat ainutlaatuisia jokaiselle säikeelle, kun taas sharedCounter heijastaa yhteistä tulosta kaikille säikeille, joka voi vaihdella säikeiden suoritusjärjestyksen mukaan.
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(); } }
Ja kun tämä ohjelma suoritetaan, saamme seuraavan tuloksen:
Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1
Kuten huomaat, sharedCounter-muuttujaa kasvatetaan eri säikeissä, kun taas threadLocalCounter-muuttuja säilyttää saman arvon jokaisessa säikeessä, koska jokaisella säikeellä on oma threadLocalCounter-instanssi, joka on riippumaton muista säikeistä.
Kuten saatat huomata, koodi sisältää staattisen metodin ThreadLocal.withInitial(), joka asettaa muuttujalle alkuarvon sen luomisen yhteydessä.
ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);
remove() -metodia ThreadLocal -luokassa käytetään poistamaan nykyiseen säikeeseen liitetty arvo.
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()); } }
Ohjelman suorituksen tuloksena:
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
Ohjelma määrittää jokaiselle säikeelle yksilöllisen arvon ThreadLocal-muuttujaan ja näyttää tämän arvon ennen ja jälkeen remove()-metodin kutsumisen. Kun arvo on poistettu remove()-metodilla, ThreadLocal palauttaa null seuraavilla get()-kutsuilla.
ThreadLocal-muuttujassa olevia tietoja ei poisteta automaattisesti, vaan ne on poistettava erikseen!
Miksi arvo täytyy vapauttaa?
Arvon vapauttaminen on tärkeää muistivuotojen estämiseksi. ThreadLocal säilyttää arvot säikeisiin sidotussa erityisessä kartassa, joka on sidottu säikeisiin. Jos arvoa ei poisteta, se jää karttaan, vaikka säikeen käyttö olisi päättynyt, mikä johtaa tarpeettomien olioiden säilymiseen muistissa ja lopulta muistivuotoihin.
1. Mikä on ThreadLocalin käytön ratkaisema pääongelma?
2. Mikä on ThreadLocal-muuttujan alkuarvo, kun se luodaan withInitial()-metodilla?
3. Mitä tapahtuu, jos et kutsu remove()-metodia ThreadLocal-muuttujalle pitkäikäisissä säikeissä?
Kiitos palautteestasi!
Kysy tekoälyä
Kysy tekoälyä
Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme
Can you explain more about how ThreadLocal prevents memory leaks?
What are some common use cases for ThreadLocal in real-world applications?
How does ThreadLocal differ from using synchronized blocks or other thread-safety mechanisms?
Awesome!
Completion rate improved to 3.33
ThreadLocal
Pyyhkäise näyttääksesi valikon
ThreadLocal mahdollistaa monisäikeisyyteen liittyvien mekanismien kuten synkronoinnin välttämisen, sillä ThreadLocal-datan saa käyttöön vain yksittäisessä säikeessä.
Kuvittele pankkisovellus, jossa jokaisella asiakkaalla on oma tili. Jos useat asiakkaat käyttävät sovellusta samanaikaisesti, heidän tilinsä tulee pysyä erillään. Käyttämällä ThreadLocal:ia jokainen säie (asiakas) saa oman tietokappaleensa (tili), mikä varmistaa, että se ei vaikuta muiden säikeiden tietoihin.
ThreadLocalin käyttö
ThreadLocal tarjoaa get() metodin ja set() metodin, jotka ovat itsestään selviä.
get() – hakee arvon ThreadLocal muuttujasta.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.get();
set() – asettaa arvon ThreadLocal muuttujaan.
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(10);
Luodaan ohjelma, jossa verrataan yksinkertaista muuttujaa ja ThreadLocal-muuttujaa.
Jokaisella säikeellä on oma erillinen threadLocalCounter, kun taas sharedCounter-arvoa muutetaan ja jaetaan kaikkien säikeiden kesken. Ohjelman tuloste osoittaa, että threadLocalCounter-arvot ovat ainutlaatuisia jokaiselle säikeelle, kun taas sharedCounter heijastaa yhteistä tulosta kaikille säikeille, joka voi vaihdella säikeiden suoritusjärjestyksen mukaan.
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(); } }
Ja kun tämä ohjelma suoritetaan, saamme seuraavan tuloksen:
Shared Counter: 1
Shared Counter: 2
Shared Counter: 3
ThreadLocal Counter: 1
ThreadLocal Counter: 1
ThreadLocal Counter: 1
Kuten huomaat, sharedCounter-muuttujaa kasvatetaan eri säikeissä, kun taas threadLocalCounter-muuttuja säilyttää saman arvon jokaisessa säikeessä, koska jokaisella säikeellä on oma threadLocalCounter-instanssi, joka on riippumaton muista säikeistä.
Kuten saatat huomata, koodi sisältää staattisen metodin ThreadLocal.withInitial(), joka asettaa muuttujalle alkuarvon sen luomisen yhteydessä.
ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0);
remove() -metodia ThreadLocal -luokassa käytetään poistamaan nykyiseen säikeeseen liitetty arvo.
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()); } }
Ohjelman suorituksen tuloksena:
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
Ohjelma määrittää jokaiselle säikeelle yksilöllisen arvon ThreadLocal-muuttujaan ja näyttää tämän arvon ennen ja jälkeen remove()-metodin kutsumisen. Kun arvo on poistettu remove()-metodilla, ThreadLocal palauttaa null seuraavilla get()-kutsuilla.
ThreadLocal-muuttujassa olevia tietoja ei poisteta automaattisesti, vaan ne on poistettava erikseen!
Miksi arvo täytyy vapauttaa?
Arvon vapauttaminen on tärkeää muistivuotojen estämiseksi. ThreadLocal säilyttää arvot säikeisiin sidotussa erityisessä kartassa, joka on sidottu säikeisiin. Jos arvoa ei poisteta, se jää karttaan, vaikka säikeen käyttö olisi päättynyt, mikä johtaa tarpeettomien olioiden säilymiseen muistissa ja lopulta muistivuotoihin.
1. Mikä on ThreadLocalin käytön ratkaisema pääongelma?
2. Mikä on ThreadLocal-muuttujan alkuarvo, kun se luodaan withInitial()-metodilla?
3. Mitä tapahtuu, jos et kutsu remove()-metodia ThreadLocal-muuttujalle pitkäikäisissä säikeissä?
Kiitos palautteestasi!