带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(9)https://developer.aliyun.com/article/1340060?groupCode=taobaotech
ThreadLocal原理
Thread 内部维护了一个 ThreadLocal.ThreadLocalMap 实例(threadLocals),ThreadLocal 的操作都是围绕着 threadLocals 来操作的。
threadLocal.get()方法
1 |
/** |
|
2 |
|
* Returns the value in the current thread's copy of this |
3 |
|
* thread-local variable. If the variable has no value for the |
4 |
|
* current thread, it is first initialized to the value returned |
5 |
|
* by an invocation of the {@link #initialValue} method. |
6 |
|
* |
7 |
|
* @return the current thread's value of this thread-local |
8 |
|
*/ |
public T get() { // 1. 获取当前线程 Thread t = Thread.currentThread(); // 2. 获取当前线程内部的ThreadLocalMap变量t.threadLocals; ThreadLocalMap map = getMap(t); // 3. 判断map是否为null if (map != null) { // 4. 使用当前threadLocal变量获取entry ThreadLocalMap.Entry e = map.getEntry(this); // 5. 判断entry是否为null if (e != null) { // 6.返回Entry.value @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } // 7. 如果map/entry为null设置初始值 return setInitialValue(); } /** * Variant of set() to establish initialValue. Used instead * of set() in case user has overridden the set() method. * * @return the initial value */ private T setInitialValue() { // 1. 初始化value,如果重写就用重写后的value,默认null T value = initialValue(); // 2. 获取当前线程 Thread t = Thread.currentThread(); // 3. 获取当前线程内部的ThreadLocalMap变量 ThreadLocalMap map = getMap(t); if (map != null) // 4. 不为null就set, key: threadLocal, value: value map.set(this, value); else // 5. map若为null则创建ThreadLocalMap对象 createMap(t, value); return value; } /** *Create the map associated with a ThreadLocal. Overridden in *InheritableThreadLocal. * *@param t the current thread *@param firstValue value for the initial entry of the map */ void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } /** *Construct a new map initially containing (firstKey, firstValue). *ThreadLocalMaps are constructed lazily, so we only create *one when we have at least one entry to put in it. */ ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) { // 1. 初始化entry数组,size: 16 table = new Entry[INITIAL_CAPACITY]; // 2. 计算value的index int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); // 3. 在对应index位置赋值 table[i] = new Entry(firstKey, firstValue); // 4. entry size size = 1; // 5. 设置threshold: threshold = len * 2 / 3; setThreshold(INITIAL_CAPACITY); } /** *Set the resize threshold to maintain at worst a 2/3 load factor. */ private void setThreshold(int len) { threshold = len * 2 / 3; }
带你读《2022技术人的百宝黑皮书》——合理使用线程池以及线程变量(11)https://developer.aliyun.com/article/1340058?groupCode=taobaotech