ThreadLocal principle role, using weak references reasons, application examples

A. Principle

  ThreadLocal is a class, he has a get, set method, you can play a save to get the role of a certain value. But get, set method of this class is a bit special, each thread calls his get, set operations interfere with each other, because of his specific ways:

public T GET () { 
        the Thread t = Thread.currentThread ();   // first determine calling my thread 
        ThreadLocalMap the Map = getMap (t);   // according to call my thread, found objects ThreadLocalMap this thread 
        IF (= the Map! null ) { 
            ThreadLocalMap.Entry E = map.getEntry ( the this );   // to ThreadLocal object key, to find the corresponding element 
            IF (E =! null ) { 
                @SuppressWarnings ( "an unchecked" ) 
                T Result = (T) e.Value ;    // speaking element value returned 
                return Result; 
            } 
        }
        return setInitialValue ();   // if the calling thread is not my ThreadLocalMap object, the initial value is returned 
    }
public  void the SET (T value) { 
        the Thread t = Thread.currentThread ();   // first determine which thread is calling my 
        ThreadLocalMap the Map = getMap (t);   // gets called my thread ThreadLocalMap 
        IF (= the Map! null ) 
            map.set ( the this , value);   // If there is a thread that map, on this ThreadLocal target set for the key's value 
        the else 
            CreateMap (t, value);    // If the thread is not yet map, and then create a setting 
    }

ThreadLocalMap ThreadLocal is an inner class, in order not to cause confusion, we can see him as an ordinary class. ThreadLocalMap fact, similar to HashMap, but also to obtain a value (key is ThreadLocal objects) through the key, is stored in an array of key-value pairs, zipper method to resolve conflicts. A Thread class holds a ThreadLocalMap instance.

Can also be seen by the above source: Reason ThreadLocal thread without disturbing each other's operation is that it's set, get method is to first get the current thread, and then modify the operating member attribute this thread object. In other words, calling ThreadLocal object set, get method is in fact a member of the operating properties of the current thread, but these attributes are found as key by ThreadLocal objects only. To understand the value concept, see figure below:

 

Brief summary of the process: There ThreadLocal objects tl, thread t call tl.get (), then go to the thread ThreadLocalMap properties of the object's t find an entry, if the return true entry.key == tl, then this entry is the target entry, this entry .value is our goal.

ThreadLocal object is just a value of access to it, providing a set, get the entrance, at the same time as the key to getting and setting the target value. The real goal is to effectively belong to the thread object privately held, the value obtained by natural ThreadLocal objects will not be affected by other threads affect it.

 

II. Usage Example

public class ThreadLocalTest {
 
    private static ThreadLocal<Integer> tl = new ThreadLocal<Integer>();
 
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            tl.set(1);
            tl.get();
            .........
        });
    }
}

Understand the principles of ThreadLocal, very simple to use, pay attention to the definition of the position of ThreadLocal object, check the scope to ensure that it can be to use the thread to access.

 

III. Entry on weakly typed references

  If you read ThreadLocalMap will find the source of Entry, Entry of the key is weak references:

static  class the Entry the extends ? WeakReference <ThreadLocal <>> {
             / ** at The Associated value with the this ThreadLocal. * / 
            Object value; 

            the Entry (ThreadLocal <>? k, Object v) {
                 Super (k);   // inherited a weak reference Therefore reference herein to a subject ThreadLcoal weak point K 
                value = V; 
            } 
        }

Why do you do that? Look at the following this scenario:

public void func1() {
        ThreadLocal tl = new ThreadLocal<Integer>(); //line1
         tl.set(100);   //line2
         tl.get();       //line3
}

line1 a built ThreadLocal objects, t1 is a strong reference point to the object; after line2set, a new Entry, entry by source objects found in the k weak references to the object. Figure:

 

When func1 method is finished, the stack frame is destroyed, there will be no strong references tl, but this time ThreadLocalMap thread in an entry of k reference also points to this object. If the reference is a strong reference k, k will lead ThreadLocal target point and point to objects v gc can not be recycled, resulting in a memory leak, but weak references not have this problem (weak and strong references and other reference here is not to say ). When using weak references, you can make the ThreadLocal objects are successfully recovered after the method is finished, and the entry of k reference point is null, after which we call the get, set, or remove methods, it will try to remove the key to null entry, can be released value memory occupied by the object.

In summary is this: Create a ThreadLocal object method, there is a strong reference to it, after the call set (), ThreadLocalMap target thread in the Entry objects have a reference point to it. If the latter is the reference method will make strong references executed, strong references to the destruction of the object can not be recovered, causing serious memory leak.

 

Note : Although a weak reference to ensure that the ThreadLocal object k points can be recovered in a timely manner, but the value of the object v points to is the need to call ThreadLocalMap get, we found that k is null will go to recover the entire entry, value when set, and therefore can not be weak references to ensure that memory is completely non-disclosure. We do not want to use after a ThreadLocal object manually call remoev method to remove it, especially in the thread pool, just a memory leak problem because the threads in the pool is reusable, which means this thread ThreadLocalMap objects are also reusable, if we do not call manually remove method, then the thread is likely to get back to the left on the threads down the value value, causing bug.

 

IV. Examples of use

  From the characteristics of the ThreadLocal class to know its use, and it can be seen as variables specific to the thread (the thread is actually through it to find one of your own Entry properties of the object), without interference from other threads, some threads of records information. Scope is rather special, it follows the thread of life, regardless of which method to perform a thread of which class, I can always use get () method out with. For example: In the web in the background, you can request information http wrapper to ThreadLocal object is assumed to be tl, execute this request before the thread begins execution tl.set (httpRequest), then the processing of the request thread no matter where execution, you can () Get the current request information from the tl.get.

  Spring is so RequestContextHolder the operation section so that in use, can be obtained the request information (when programming section itself can be acquired only the method name + Method of parameter information):

Guess you like

Origin www.cnblogs.com/shen-qian/p/12108655.html