On ThreadLocal source

ThreadLocal commonly known as thread-local, as the name implies, it offers is enclosed in a thread local variable, meaning that only the current thread to set, get, remove and other operations, and it will be with the demise of the thread GC.

Schematic

Before we look at the source code, we look at a map

As shown, each thread Thread object contains a ThreadLocalMap, which is a simplified version of a hashmap achieved. So naturally, ThreadLocalMap contains a hash table. Hash table is stored in key / value data in the form. key is ThreadLocal instance, value is the data that you want to set.

You go through the current ThreadLocal setting data, such as:

threadLocal.set("lay");

1, according to one threadLocal contained the hashCode (threadLocal identifies the current instance), is calculated on the fall position of the hash table index;

2, then as threadLocal key + data to be stored together on a storage node of the hash table;

3, if the node data already exists, then the right to find the next node, if the node is not the right side, then recycled to an index of 0, and so on;

4, if there is no sufficient data storage location, then it will be the expansion and re-hash.

ThreadLocalMap are combined in a Thread object inside, so when will lose the thread of extinction ThreadLocalMap references, thereby GC, and ThreadLocalMap data stored inside, if there are no other words quoted held that the same will be recovered GC. And, external can not directly access ThreadLocalMap, and ThreadLocal class and Thread in the same package so you can only be accessed through it, thus ensuring ThreadLocalMap closed internal thread.

DEMO

We start with a simple DEMO

Source resolve

 First, construct a static ThreadLocal variable, which had nothing dry construction method

set()

Click to go to set () method

先获取了当前线程Thread对象,然后从Thread对象里面获取ThreadLocalMap对象。初次调用的话ThreadLocalMap为空,那么进入createMap方法创建一个。

进createMap看看怎么创建的

构造一个ThreadLocalMap的时候,把当前ThreadLocal的实例传入,并把值也传入,看看构造方法

构造方法先初始化了一个空的hash表,然后根据threadLocal的hashCode计算出索引的位置,再以threadLocal作为key创建了一个节点(Entry),设置大小为1,并设置扩容的阈值。这样一个初始化的ThreadLocalMap就构建完了。

我们回到set的时候判断ThreadLocalMap是否为空上来,如果它不为空直接调用ThreadLocalMap的set方法设置值。进入set方法

set方法有点长,原理比较简单。就是先根据threadLocal的hashCode计算出索引位置,然后比对threadLocal对象是不是当前这个对象,遍历整个hash表直到找到对象,或者完全找不到对象。前者直接赋值,后者创建一个节点。创建节点的话会判断需不需要扩容,如果需要的话重新进行hash计算。

get()

看完set方法,再看get方法就显得很简单了

一样是先拿到Thread中的ThreadLocalMap,如果Map为空,那么返回一个初始值。如果不为空,找到Entry节点,如果节点找了返回节点数据,否则返回初始值。

remove()

remove方法,一样很简单

找到ThreadLocalMap,调用remove方法,传入threadLocal实例。进入remove看看

遍历hash表,找到该key对象的Entry,然后做了清理操作。

总结

 ThreadLocal实际上是包含了ThreadLocalMap的数据操作,而ThreadLocalMap组合在Thread中,随着Thread消亡。

 

Guess you like

Origin www.cnblogs.com/lay2017/p/11058285.html