ThreadLocal application of the principle and resolve common issues

ThreadLocal we are more used to, the relevant data is stored in multiple threads at the thread very appropriate. But a lot of times we do not go in-depth understanding of how it works.

The preferred asked a few questions, then answered their questions on these issues later.

  1. ThreadLocal mentioned, we often say that ThreadLocal is weak references, then ThreadLocal exactly how a weak reference it?
  2. How did it ThreadLocal can be used as thread-local variables it?
  3. When you create a ThreadLocal variable, why you should use static modification?
  4. Our argument more than a ThreadLocal memory leaks What the hell?

Entered, briefly understand the next ThreadLocal and class structure Thread, ThreadLocal of:

 

 You can see, ThreadLocal class have internal ThreadLocalMap, ThreadLocalMap another internal class Entry.

Thread class has this source:

class Thread implements Runnable {

    ...省略若干代码

    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    /*
     * InheritableThreadLocal values pertaining to this thread. This map is
     * maintained by the InheritableThreadLocal class.
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

 

 By Thread source we learned that the object is held by Thread ThreadLocal of ThreadLocalMap, this is particularly important, relevant data are thread through ThreadLocalMap stored, rather than ThreadLocal.

At this point we have concluded as shown below:

Thread of ThreadLocals ThreadLocal.ThreadLocalMap properties directly associated with, and in no way related ThreadLocal

 

So ThreadLocal is to do what? In fact, ThreadLocal thread can be seen as operating ThreadLocalMap of tools, ThreadLocal storm drain two public methods get () and set (T) is used to get and set ThreadLocalMap.

Look set source method:

 

1     public void set(T value) {
2         Thread t = Thread.currentThread();
3         ThreadLocalMap map = getMap(t);
4         if (map != null)
5             map.set(this, value);
6         else
7             createMap(t, value);
8     }

 

 

 

 

 

 

 The fifth line from the source we can get two important messages:

  • Getting ThreadLocalMap, using the current Thread object t as a parameter.

    Achieve getMap (t) process is very simple:

      

    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

 

    It returns the Thread of threadLocals attribute to verify the code on: " thread local variable " in the Thread object storage threadLocals properties , and ThreadLocal itself does not matter. ThreadLocal can be used as tools to access.

    Here we have the first two questions: ThreadLocal is how to do it can be used as thread-local variables already have the answer you, all operations are actually on Thread at threadLocals operation, so cross-thread operation will not cause problems, because getMap ( ) always returns the current thread threadLocals property.

 

  • ThreadLocalMap is a structure similar to the Map key-value pairs, where the incoming key is a fixed value this, this this is not a thread object yo, is the current ThreadLocal objects, value which we passed parameters.

    Little friends is not it strange why should this as a key it? This article side-tracked by the beginning of our first question: the weak reference!

    Follow map.set (this, value); source code to see what:

 1         private void set(ThreadLocal<?> key, Object value) {
 2 
 3             Entry[] tab = table;
 4             int len = tab.length;
 5             int i = key.threadLocalHashCode & (len-1);
 6 
 7             for (Entry e = tab[i];
 8                  e != null;
 9                  e = tab[i = nextIndex(i, len)]) {
10                 ThreadLocal<?> k = e.get();
11 
12                 if (k == key) {
13                     e.value = value;
14                     return;
15                 }
16 
17                 if (k == null) {
18                     replaceStaleEntry(key, value, i);
19                     return;
20                 }
21             }
22 
23             tab[i] = new Entry(key, value);
24             int sz = ++size;
25             if (!cleanSomeSlots(i, sz) && sz >= threshold)
26                 rehash();
27         }

 

  View constructor 23 lines of Entry:

1         static class Entry extends WeakReference<ThreadLocal<?>> {
2             /** The value associated with this ThreadLocal. */
3             Object value;
4 
5             Entry(ThreadLocal<?> k, Object v) {
6                 super(k);
7                 value = v;
8             }
9         }

 

    Entry is only a constructor, the constructor accepts two parameters k and v, k is the current ThreadLocal objects, v is thread-related data I want to store. The code marked by the red part we can see that for k using weak references , but not the value, value is a strong reference . Thus the first question has been the truth, everyone said ThreadLocal weak references is actually ThreadLocalMap and ThreadLocal is weak references relationship.

    Why such a design?

    The current reference relationship as shown at our first choice finishing:

    

 

 

     value is generally thread-related data, the thread after the recovery value -> null, strong reference does not exist. But ThreadLocal object life cycle and are not necessarily related threads, ThreadLocal object is still referenced by another thread after thread may die out, if you use strong-quoted, ThreadLocalMap objects can not release the memory, a memory leak occurs. The use of weak references to secure more weak references to objects will be garbage collection occurs when gc.

 

Why use static modification when the problem has already been mentioned in 1 and 2 above, continue to look at the issue 3, create a ThreadLocal object?

  Personal feeling is based on two considerations:

  • The first is to avoid recreating ThreadLocal object, use the same ThreadLocal object and a plurality ThreadLocal objects no impact on the code itself, it is not necessary to repeatedly create multiple objects.
  • ThreadLocal extend the life cycle, easy to use.

   Many places online to static and memory leaks linked to forgive me did not see it has anything to do both.

    

Finally came to the fourth question, we are also concerned about the memory leak anymore.

  We understand that there are two references to the relationship by reference to the above diagram, are key weak reference value and strong references. Weak references preferred not lead to memory leaks, because the object referenced by weak gc occurs when there is likely to be recovered. and so. . . A memory leak occurs in this relationship strong references.

  Because now the thread switching overhead is relatively large, it is now widespread use of technology to avoid frequent thread pool thread creation. In the thread pool thread will not die, it will be reused, so. . . . On top of strong references not released, and a memory leak just happened. In fact, I see on JDK8 is java already did some work, such as the implementation of traversal key set the next time the operation is null Entry object and release the value of the reference. Although java itself to do some work, finished strongly recommend the use of ThreadLocal implementation of the initiative to eliminate references to the remove method relationship.

  The end of the article, if flawed, welcome that.

 

Guess you like

Origin www.cnblogs.com/dreamowneryong/p/11697469.html