Usually often say ThreadLocal, today solve it

  • Foreword
  • First, understand the role of ThreadLocal
  • Two, ThreadLocal simple to use
  • Three, ThreadLocal principle
    • 3.1 ThreadLocal access process
    • 3.2 Object inquiry ThreadLocalMap
    • Recovery 3.3 ThreadLocal object
  • Four, ThreadLocal scenarios

Foreword

ThreadLocal is very important in a multi-threaded processing tools, such as database connection pool storage Connection, stored parameters such as the role of local interviews are often asked to principle and its application, this paper from the outside to the mainland to learn about ThreadLocal.

First, understand the role of ThreadLocal

As the name suggests is a ThreadLocal thread private local variable storage container, can be understood as each thread has its own dedicated storage container, which is used to store thread private variables, in fact, it is just a shell, internal access is really a Map, behind carefully explain. Each thread through set()and get()access variables between multiple threads can not access their local variables, is equivalent to the establishment of a separator between each thread. As long as the thread is active, ThreadLocal instances it is the corresponding accessible after the thread has been terminated, all instances of it will be garbage collected. In short remember one sentence: ThreadLocal stored variables belong to the current thread .

Two, ThreadLocal simple to use

Man of few words said, look at a simple case of ThreadLocal

Code:

public class Test implements Runnable { private static AtomicInteger counter = new AtomicInteger(100); private static ThreadLocal<String> threadInfo = new ThreadLocal<String>() { @Override protected String initialValue() { return "[" + Thread.currentThread().getName() + "," + counter.getAndIncrement() + "]"; } }; @Override public void run() { System.out.println("threadInfo value:" + threadInfo.get()); } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new Test()); Thread thread2 = new Thread(new Test()); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("threadInfo value in main:" + threadInfo.get()); } } 

Output:

threadInfo value:[Thread-0,100] threadInfo value:[Thread-1,101] threadInfo value in main:[main,102] 

The code I use to store information ThreadLocal thread, its format [线程名,线程ID], defined variable is static. You can see the results from the run out of each thread includes access to the main thread of threadInfovalues obtained are not the same, and the information is stored in the information in this thread, but also should permit the above sentence ThreadLocal stored variables belong to the current thread .

Three, ThreadLocal principle

3.1 ThreadLocal access process

Principle start parsing the source code to start, first of all look at the ThreadLocal.set()method

// ThreadLocal set methods
 public void set (T value ) { // get the current thread object T the Thread = the Thread . CurrentThread ( ) ; // attribute obtaining threadLocals the thread (ThreadLocalMap objects) ThreadLocalMap Map = the getMap (T ) ; IF (Map =! null ) Map . SET ( the this , value ) ; the else CreateMap (T , value ) ; } ThreadLocals defined ThreadLocal // Thread class .ThreadLocalMap ThreadLocals =null ; // in the ThreadLocal getMap method ThreadLocalMap getMap (the Thread T ) { return T .threadLocals ; } // in the ThreadLocal CreateMap methods // Create a thread ThreadLocalMap object and assigned to ThreadLocals void CreateMap (the Thread T , T firstValue ) {T . ThreadLocals = new new ThreadLocalMap ( the this , firstValue ) ; }

See the source code from the set method which is the value stored in the ThreadLocalMapclass, this class is part of ThreadLocalan inner class, but the Threadclass also defined threadLocalsvariables, methods of operation object get is ThreadLocalMap, that is the key to the storage and retrieval of virtually that ThreadLocalMapcategory. Which is based on ThreadLocal class is key, stored value value, and ThreadLocal is defined in the properties of each thread, which will achieve a "ThreadLocal thread privatization" function, each time starting with the current thread threadLocals acquired property is obtained ThreadLocalMap subject to ThreadLocal object as a value corresponding to the access key .

3.2 Object inquiry ThreadLocalMap

ThreadLocalMapObject class is an internal class ThreadLocal, wherein it is a simple the Map, the value of each stored Entry is packed for storage, the following source code is Entry

static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } 

Entry is ThreadLocalMap inner class, carefully observe its source found, it inherited a weak reference of a ThreadLocal. Recall that four kinds of Java references: strong references, soft references, weak references, phantom references. A strong reference is created out of the new object, as long strong references exist, the garbage collector will never recover the references; soft references (SoftReference) is about to be reclaimed when memory is fully occupied; weak references (WeakReference) is used to describe non-essential object, but its strength is weaker than some of the soft references, objects are associated with weak references only to survive until the next GC occurs when the garbage collector job, regardless of the adequacy of current memory will recover lost objects in that class; phantom reference , also known as virtual ghost references or references (phantom reference), which is a reference to the weakest relationship. Whether there is a phantom reference object has completely will not affect their survival time, can not be achieved through the phantom reference object instance, may be recovered at any time. More explanation and examples readers can go before I wrote this article to read:

Recovery 3.3 ThreadLocal object

Entry is a weak reference, because it does not affect the behavior of GC ThreadLocal, if it is strong references, then, in the course of the thread is running, we no longer use a ThreadLocal, ThreadLocal will be set to null, but ThreadLocal thread in the ThreadLocalMap there are references, cause it not to be recovered GC. The Entry declared WeakReference, ThreadLocal set to the null, thread ThreadLocalMap it is not strong references, ThreadLocal can be recovered GC.

//  ThreadLocal中的remove方法
public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); } // ThreadLocalMap中的remove方法 private void remove(ThreadLocal<?> key) { Entry[] tab = table; int len = tab.length; int i = key.threadLocalHashCode & (len-1); for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { if (e.get() == key) { e.clear(); expungeStaleEntry(i); return; } } } 

Memory leak problems

ThreadLocalMap life cycle with the same thread, but not necessarily ThreadLocal, ThreadLocal might want to be finished on the use of recycled, but this time the thread may not be immediately terminated, will continue to run (such as thread pool reused), If ThreadLocal object exists only weak references, then the next garbage collection time is bound to be cleared away.

If the case is not strong references ThreadLocal outside under, when garbage collection will be cleaned out, so that ThreadLocalMap used in this ThreadLocal key will be cleared away. However, a strong reference value will not be cleared, so that there will be key to null value

In ThreadLocalMap, call set (), get (), remove () method when will clean out the key to null records. Is after null, ThreadLocalMap in the presence of key ThreadLocal set to null value, then it may be a memory leak, only manually invoke remove()methods to avoid, so when we finished using ThreadLocal variables, try to use threadLocal.remove () to clear and avoid threadLocal = null operation . The method of recovery is completely remove the object, by threadLocal=nullsimply letting out ThreadLocal references, but which still exists in the Entry ThreadLocalMap, the subsequent processing needs.

Four, ThreadLocal scenarios

  • More complex processing operations, instead of using the display parameters passed ThreadLocal.
  • ThreadLocal can be used for the database connection pool to save the Connection object, so you can make multiple acquisitions within the thread of connection is the same (Spring in the DataSource is used ThreadLocal).
  • Session management Session, Session is stored in the ThreadLocal in the thread processing multiple treatments is always a Session the session.

Guess you like

Origin www.cnblogs.com/tiancai/p/11608684.html