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

How to use ThreadLocal

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

Share

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

This article is about how to use ThreadLocal. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

Basic use of ThreadLocal

Create a ThreadLocal object:

Private ThreadLocal localInt = new ThreadLocal ()

The above code creates a localInt variable, and since ThreadLocal is a generic class, the type of localInt is specified as an integer.

The following shows how to set and get the value of this variable:

Public int setAndGet () {localInt.set (8); return localInt.get ();}

The above code sets the value of the variable to 8, and then gets this value.

Because of the value set in ThreadLocal, only the current thread can see it, which means that you cannot initialize the value for it through other threads. To make up for this, ThreadLocal provides a withInitial () method to uniformly initialize the value of ThreadLocal for all threads:

Private ThreadLocal localInt = ThreadLocal.withInitial (()-> 6)

The above code sets the initial value of ThreadLocal to 6, which is visible to all threads.

The realization principle of ThreadLocal

The ThreadLocal variable is only visible within a single thread, so how does it do that? Let's start with the most basic get () method:

Public T get () {/ / get the current thread Thread t = Thread.currentThread (); / / each thread has its own ThreadLocalMap, / / ThreadLocalMap holds all the ThreadLocal variables ThreadLocalMap map = getMap (t) If (map! = null) {/ / the key of ThreadLocalMap is the current ThreadLocal object instance. / / multiple ThreadLocal variables are ThreadLocalMap.Entry e = map.getEntry (this) in this map. If (e! = null) {@ SuppressWarnings ("unchecked") / / the value taken from map is the ThreadLocal variable T result = (T) e.value; return result;}} / / if map is not initialized, initialize return setInitialValue ();} here.

As you can see, the so-called ThreadLocal variable is stored in the map of each thread. This map is the threadLocals field in the Thread object. As follows:

ThreadLocal.ThreadLocalMap threadLocals = null

ThreadLocal.ThreadLocalMap is a special Map whose key for each Entry is a weak reference:

Static class Entry extends WeakReference k = e.get (); / / if found, return if (k = = key) return e; if (k = = null) / / if key is null, the weak reference has been recycled / / then the value in it should be recycled here expungeStaleEntry (I) Else / / if key is not the one you are looking for, then there is a hash conflict. Here is to deal with the conflict and find the next entry I = nextIndex (I, len); e = tab [I];} return null;}

What is really used to recycle value is the expungeStaleEntry () method, which is called directly or indirectly to clean up the value in both the remove () and set () methods:

As you can see from here, ThreadLocal has made a lot of efforts to avoid memory leaks. Not only do you use weak references to maintain the key, but you also check whether the key is recycled on each operation, and then the value is recycled.

But you can also see that ThreadLocal is not 100% guaranteed against memory leaks.

For example, unfortunately, your get () method always accesses several existing ThreadLocal, so the cleanup action will not be performed, and if you don't have a chance to call set () and remove (), the memory leak will still occur.

Therefore, it is still a good habit to call remove () actively when you don't need this ThreadLocal variable, which is good for the whole system.

Hash conflict handling in ThreadLocalMap

The implementation of ThreadLocalMap as a HashMap and java.util.HashMap is different. For java.util.HashMap, the linked list method is used to handle conflicts:

However, for ThreadLocalMap, it uses a simple linear detection method, and if an element conflict occurs, the next slot is used to store:

Specifically, the whole process of set () is as follows:

ThreadLocal--InheritableThreadLocal that can be inherited

In the actual development process, we may encounter such a scenario. The main thread has a child thread, but we want to be able to access the ThreadLocal object in the main thread in the child thread, which means that some data needs to be passed between parent and child threads. Like this:

Public static void main (String [] args) {ThreadLocal threadLocal = new ThreadLocal (); IntStream.range (0d10) .forEach (I-> {/ / the sequence number of each thread, hoping to get threadLocal.set (I) in the child thread) / / here comes a child thread, and we want to be able to access the above threadLocal new Thread (()-> {System.out.println (Thread.currentThread (). GetName () + ":" + threadLocal.get ());}) .start (); try {Thread.sleep (1000);} catch (InterruptedException e) {e.printStackTrace () });}

Execute the above code and you will see:

Thread-0:null Thread-1:null Thread-2:null Thread-3:null

Because there is no threadLocal in the child thread. If we want the child line to see the ThreadLocal of the parent thread, then we can use InheritableThreadLocal. As the name implies, this is a ThreadLocal that supports inter-thread parent-child inheritance, using InheritableThreadLocal for the threadLocal in the above code:

InheritableThreadLocal threadLocal = new InheritableThreadLocal ()

If you execute it again, you can see:

Thread-0:0 Thread-1:1 Thread-2:2 Thread-3:3 Thread-4:4

As you can see, each thread can access a piece of data passed from the parent process. Although InheritableThreadLocal looks convenient, there are still a few points to note:

The variable is passed when the thread is created. If it is not a new thread, but a thread in the thread pool, it will not work.

Variable assignment is copied from the map of the main thread to the child thread, and their value is the same object. If the object itself is not thread safe, then there will be thread safety problems.

Thank you for reading! This is the end of the article on "how to use ThreadLocal". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!

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