In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "what are the common methods, usage scenarios and matters needing attention of ThreadLocal". Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "what are the common methods, usage scenarios and matters needing attention of ThreadLocal?"
Catalogue
1. ThreadLocal detailed explanation
2. Usage scenarios of ThreadLocal
3. Source code analysis of common methods
3.1 initialValue method
3.2 set (T value) method
3. 3 get method
3.4 Summary
3.4 ThreadLocalMap data structure
4. Side effects of ThreadLocal
4.1 ThreadLocal causes dirty data
4.2 memory leaks caused by ThreadLocal
5. ThreadLocal memory leak solution and remove method source code analysis
1. ThreadLocal detailed explanation
Since the JDK1.2 version, Java has provided java.lang.ThreadLocal,ThreadLocal to provide independent copies of variables for each thread, which can isolate data between threads, and each thread can access its own internal copy variables.
Thread context ThreadLocal, also known as "thread safe", ThreadLocal can bind the specified variable to the current thread, and the threads are isolated from each other and hold different object instances, thus avoiding the competition of data resources.
2. Usage scenarios of ThreadLocal
When passing objects across layers, you can consider ThreadLocal to avoid passing methods multiple times and breaking the constraints between layers.
Data isolation between threads.
Perform transaction operations to store thread transaction information.
Note:
ThreadLocal is not a technology to solve the problem of sharing resources under multithreading. In general, the ThreadLocal of each thread stores a brand-new object (created by the new keyword). If the multithreaded ThreadLocal stores an object reference, it will face concurrency problems such as resource competition and data inconsistency.
3. Common methods Source Code parsing 3.1 initialValue method protected T initialValue () {return null;}
This method specifies an initialization value for the data type saved by ThreadLocal and returns null by default in ThreadLocal. However, you can override the initialValue () method for data initialization.
If you are using the Supplier function interface provided by Java8, it is more simplified:
/ / withInitial () actually creates a subclass SuppliedThreadLocal of ThreadLocal, rewriting initialValue () ThreadLocal threadLocal = ThreadLocal.withInitial (Object::new); 3.2set (T value) method
Mainly stores the specified data.
Public void set (T value) {/ / gets the current thread Thread.currentThread () Thread t = Thread.currentThread (); / / gets the associated ThreadLocalMap data structure ThreadLocalMap map = getMap (t); if (map! = null) / / core method based on the current thread. Set traverses the entire Entry, followed by a detailed explanation of map.set (this, value); else {/ / calls createMap () to create ThreadLocalMap,key as the current ThreadLocal instance and store data as the current value. / / ThreadLocal creates a node with the default length of 16Entry, and places KMuv in the I position (the I position is calculated in the same way as hashmap, / / the hashCode& of the current thread (entry default length-1)), and sets the threshold (default is 0) to 2max / 3 of the default length of Entry. CreateMap (t, value);}} / set the process of traversing the entire Entry private void set (ThreadLocal key, Object value) {/ / get all the Entry Entry [] tab = table; int len = tab.length; / / calculate the corner position int I = key.threadLocalHashCode & (len-1) based on the ThreadLocal object; / / Loop find for (Entry e = tab [I]; e! = null E = tab [I = nextIndex (I, len)]) {ThreadLocal k = e.get (); / / if you find the same, you will directly overwrite and return. If (k = = key) {e.value = value; return;} / / if ThreadLocal is null, directly drive out and use the new data (Value) to occupy the original location, / / this process is mainly to prevent memory leaks. If (k = = null) {/ / dispel the Entry whose ThreadLocal is null and put it in Value, which is also the key area of memory leak: replaceStaleEntry (key, value, I); return;}} / / entry is null, create a new entry, ThreadLocal is key, and store data as Value. Tab [I] = new Entry (key, value); int sz = + + size; / / compare the number of current data elements with the threshold, and clean up key for null again. If (! cleanSomeSlots (I, sz) & & sz > = threshold) / / collates the Entry. When the ThreadLocal object in the Entry is null, clean / / the previous ThreadLocal by recalculating the corner bits. Expand the capacity of rehash () if the number of Entry is greater than 3amp 4 capacity;} 3.3 get method
Get () is used to return the data backup in the current thread ThreadLocal, where the data is stored in a ThreadLocalMap data structure.
Public T get () {Thread t = Thread.currentThread (); / / get that the ThreadLocalMap object map,ThreadLocalMap is associated with the current Thread, ThreadLocalMap map = getMap (t); if (map! = null) {/ / the data stored in ThreadLocal is actually stored in ThreadLocalMap's Entry. / / and this Entry is placed in an Entry array. / / get the entry ThreadLocalMap.Entry e = map.getEntry (this) corresponding to the current ThreadLocal; if (e! = null) {/ / directly return the current data T result = (T) e.value; return result;}} / / ThreadLocalMap is not initialized. Initialize return setInitialValue () first. } / / setInitialValue method source code private T setInitialValue () {/ / specify the initialization value of Value for ThreadLocalMap T value = initialValue (); Thread t = Thread.currentThread (); / / get ThreadLocalMap according to the local thread Thread, the following method is the same as the Set method. ThreadLocalMap map = getMap (t); if (map! = null) / / if map exists, call the set () method to assign the value directly. Map.set (this, value); else / / map==null; creates ThreadLocalMap objects and associates Thread and value with createMap (t, value); return value;} 3.4.Summary
InitialValue (): initializes the value of the value attribute in ThreadLocal.
Set (): gets the current thread and gets the ThreadLocalMap data structure from ThreadLocals according to the current thread
If the data structure of ThreadLocalmap is not created, the ThreadLocalMap,key is created as the current ThreadLocal instance, and the stored data is the current value. ThreadLocal creates a node with a default length of 16Entry, and places kmurv in the I position (I position is calculated in the same way as hashmap, the hashCode& of the current thread (entry default length-1)), and sets the threshold (default is 0) to 2max 3 of the default length of Entry.
If ThreadLocalMap exists. The Entry node in the entire Map is traversed, and if the key in the entry is the same as the ThreadLocal in this thread, the data (value) is directly overwritten and returned. If ThreadLoca is null, remove the Entry whose ThreadLocal is null and put it in Value, which is also the focus of memory leaks.
Get ()
The get () method is relatively simple. Is to obtain ThreadLocalMap based on Thread. Get the data value through ThreadLocal. Note: if the ThreadLocalMap is not created, go straight to the creation process. Initialize ThreadLocalMap. And directly call the same method as the set method.
3.4 ThreadLocalMap data structure
Either the set () or get () methods can't avoid dealing with ThreadLocalMap and Entry. ThreadLocalMap is a data structure similar to HashMap (no linked list). It is only used to store data backups that threads store in ThreadLocal. All methods of ThreadLocalMap are invisible to the outside.
Entry, which is used to store data in ThreadLocalMap, is a subclass of WeakReference type. It is designed to be WeakReference so that gc can occur in JVM and can be automatically reclaimed to prevent memory overflow.
4. Side effects of ThreadLocal 4.1 ThreadLocal causes dirty data
Thread reuse produces dirty data.
Because the completion pool reuses the Thread object, the static property ThreadLocal variable of the class bound to Thread is also reused. If remove () is not explicitly called in the body of the implemented thread run () method to clean up thread-related ThreadLocal information, then if the next thread does not call set () to set the initial value, it is possible to get () to the reused thread information, including the value value of the thread object associated with ThreadLocal.
/ / java.lang.Thread#threadLocals / * ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. * / ThreadLocal.ThreadLocalMap threadLocals = memory leak caused by null;4.2 ThreadLocal
The Entry stored in ThreadLocalMap mentioned above is a subclass of WeakReference. Therefore, when JVM triggers GC (young gc,Full GC), it will lead to the recovery of Entry.
In get data, add checks to clear the Entry that has been reclaimed by the collector (WeakReference can be recycled automatically)
Private Entry getEntryAfterMiss (ThreadLocal key, int I, Entry e) {ThreadLocal k = e.get ();... If (k = = null) / / clears that key is the Entry expungeStaleEntry (I) of null. Return null;} private boolean cleanSomeSlots (int I, int n) {boolean removed = false; Entry [] tab = table; int len = tab.length; do {I = nextIndex (I, len); Entry e = tab [I]; if (e! = null & & e.get () = null) {n = len; removed = true / / clear Entry I = expungeStaleEntry (I) of key==null;}} while ((n > = 1)! = 0); return removed;}
Add checks to set data, delete the Entry that has been cleaned by the garbage collector and remove it
Private boolean cleanSomeSlots (int I, int n) {boolean removed = false; Entry [] tab = table; int len = tab.length; do {I = nextIndex (I, len); Entry e = tab [I]; if (e! = null & & e.get () = null) {n = len; removed = true / / clear Entry I = expungeStaleEntry (I) of key==null;}} while ((n > = 1)! = 0); return removed;}
Based on the above three points: ThreadLocal guarantees to a certain extent that memory leaks will not occur. However, there is a reference to ThreadlocalMap in the Thread class, which leads to the reachability of the object, so it cannot be recycled.
ThreadLocal is set to null to clear. But it is still referenced by the Thread class through ThreadLocalMap. Causes the data to be accessible. So memory is not freed, and unless the current thread ends, the Thread reference is reclaimed by the garbage collector. As shown in the figure
five
5. ThreadLocal memory leak solution and remove method source code analysis
The common way to solve ThreadLocal memory leaks is to drop remove in time after using ThreadLocal.
Public void remove () {/ / according to the current thread, get ThreadLocalMap ThreadLocalMap m = getMap (Thread.currentThread ()); if (m! = null) / / map is not null, perform the remove operation m.remove (this);} / / ThreadLocal's remove () private void remove (ThreadLocal key) {/ / gets the array where key-value is stored. Entry [] tab = table; int len = tab.length; / / determine the unique corner mark int I = key.threadLocalHashCode & (len-1) according to ThreadLocal's HashCode; for (Entry e = tab [I]; e! = null;e = tab [I = nextIndex (I, len)]) {if (e.get () = = key) {/ / if it is the same as this ThreadLocal. Set the reference to null. E.clear (); / / implement Enty and Entry.value null. Null; tab [staleSlot] .value = null; tab [staleSlot] = null; expungeStaleEntry (I); return;}} so far, I believe you have a deeper understanding of "what are the common methods, usage scenarios and matters needing attention of ThreadLocal". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.