Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the working principle and usage of ThreadLocal

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about the working principle and usage of ThreadLocal, which may not be well understood by many people. in order to make you understand better, the editor has summarized the following content for you. I hope you can get something according to this article.

What is ThreadLocal?

ThreadLocal is the manager of the attribute threadLocals or ThreadLocal.ThreadLocalMap in the thread Thread. ThreadLocal is used to give each thread a local variable to operate its own thread, which ensures thread safety through thread privacy.

ThreadLocal principle

Take the get () method, the thread's local variable is stored on the thread instance property ThreadLocalMap, ThreadLocalMap is essentially a HashMap,ThreadLocal is just a manager, when our thread needs to get its own local variable, we can directly call ThreadLocal to get the local variable.

Because the bottom layer of the get () method will first get the current thread, and then get its property value ThreadLocalMap through the current thread. If the ThreadLocalMap is empty, it will call the initialization method of ThreadLocal to get the initial value. If it is not empty, it will use the ThreadLocal as the key to obtain the corresponding value in the ThreadLocalMap under the thread.

ThreadLocal memory leak problem

The key used in the thread's property value ThreadLocalMap is a weak reference to ThreadLocal, while value is a strong reference. So, if the ThreadLocal is not strongly referenced from the outside, the key will be cleaned up during garbage collection, but the value will not be cleaned up. In this case, an Entry with a key of null appears in the ThreadLocalMap. If we don't do anything, value can never be recycled by GC, and memory leaks may occur at this time.

Therefore, in view of this situation, we have two principles:

ThreadLocal is declared private static final. JDK suggests that ThreadLocal be defined as private static, so that the problem of weak references to ThreadLocal does not exist.

Private and final try not to allow others to modify the change reference.

Static is represented as a class attribute and is recycled only at the end of the program.

Be sure to call the remove method after using ThreadLocal.

The simplest and most effective way is to remove it after use.

About InheritableThreadLocal

The InheritableThreadLocal class is a subclass of the ThreadLocal class. Each thread in ThreadLocal has its own value, and unlike ThreadLocal, InheritableThreadLocal allows a thread and all child threads created by that thread to access the values it holds.

The code example ThreadLocal uses public class ThreadLocalTest {/ / the first initialization method / * to declare static to let the ThreadLocal instance end with the end of the program, so that GC will not recycle * declare as final so that the ThreadLocal instance reference will not be replaced In this way, it will not be recycled by GC because it is replaced * both statements are intended to prevent ThreadLocal objects as key from being recycled by GC without external strong references, resulting in memory leaks, because ThreadLocal * objects in ThreadLocalMap are weak references as key and will be recycled by GC. * / private static final ThreadLocal threadLocalStr = ThreadLocal.withInitial (()-> "fresh"); private static AtomicInteger intGen = new AtomicInteger (0); / / second initialization method private static final ThreadLocal threadLocalInt = new ThreadLocal () {@ Override public Integer initialValue () {return intGen.incrementAndGet ();}}; public static void main (String [] args) throws InterruptedException {ArrayList threads = new ArrayList () For (int I = 0; I

< 2; i++) { Thread t = new Thread(() ->

{try {System.out.println (Thread.currentThread (). GetName () + "+ threadLocalInt.get ()); System.out.println (Thread.currentThread (). GetName () +" + threadLocalStr.get ()); TimeUnit.SECONDS.sleep (5); threadLocalStr.set ("bojack horseman" + threadLocalInt.get ()) System.out.println (Thread.currentThread (). GetName () + "+ threadLocalInt.get ()); System.out.println (Thread.currentThread (). GetName () +" + threadLocalStr.get ());} catch (InterruptedException e) {e.printStackTrace () } finally {threadLocalInt.remove (); threadLocalStr.remove ();}}); t.start (); threads.add (t);} TimeUnit.SECONDS.sleep (2); System.out.println (threads); System.out.println (threadLocalStr) System.out.println (threadLocalInt) } / * Thread-0 1 * Thread-1 2 * Thread-0 fresh * Thread-1 fresh * [Thread [Thread-0meme5 main], Thread [Thread-1LJ5] Main] * java.lang.ThreadLocal$SuppliedThreadLocal@1ef7fe8e * cn.vv.schedule.test.ThreadLocalTest$1@6f79caec * Thread-1 2 * Thread-1 bojack horseman2 * Thread-0 1 * Thread-0 bojack horseman1 * /} InheritableThreadLocal uses public class InheritableThreadLocalTest {/ / the first initialization method private static final InheritableThreadLocal threadLocalStr = new InheritableThreadLocal () {@ Override public String initialValue () {return "fresh" }}; private static AtomicInteger intGen = new AtomicInteger (0); / / the second initialization method private static final ThreadLocal threadLocalInt = new ThreadLocal () {@ Override public Integer initialValue () {return intGen.incrementAndGet ();}} Public static void main (String [] args) throws InterruptedException {/ / if it is InheritableThreadLocal, all child threads created by the parent thread copy a thread variable of the parent thread instead of initializing a thread variable threadLocalStr.set ("main"); ArrayList threads = new ArrayList (); for (int I = 0; I)

< 2; i++) { Thread t = new Thread(() ->

{try {System.out.println (Thread.currentThread (). GetName () + "+ threadLocalInt.get ()); System.out.println (Thread.currentThread (). GetName () +" + threadLocalStr.get ()); TimeUnit.SECONDS.sleep (5) / / Child threads are free to change their local variables threadLocalStr.set ("bojack horseman" + threadLocalInt.get ()); System.out.println (Thread.currentThread () .getName () + "+ threadLocalInt.get ()); System.out.println (Thread.currentThread () .getName () +" + threadLocalStr.get () } catch (InterruptedException e) {e.printStackTrace ();} finally {threadLocalInt.remove (); threadLocalStr.remove ();}}); t.start (); threads.add (t) } TimeUnit.SECONDS.sleep (2); System.out.println (Thread.currentThread () .getName () + "+ threadLocalStr.get ()) } / * Thread-0 2 * Thread-1 1 * Thread-0 main * Thread-1 main * main main * Thread-0 2 * Thread-0 bojack horseman2 * Thread-1 1 * Thread-1 bojack horseman1 * /} after reading the above, do you have any further understanding of the working principle and usage of ThreadLocal? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report