ThreadLocal理解
2017-11-23 10:56
239 查看
/** * Sets the current thread's copy of this thread-local variable * to the specified value. Most subclasses will have no need to * override this method, relying solely on the {@link #initialValue} * method to set the values of thread-locals. * * @param value the value to be stored in the current thread's copy of * this thread-local. */ public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } /** * Get the map associated with a ThreadLocal. Overridden in * InheritableThreadLocal. * 获取的是Thread局部变量表的数据,即能保证每个线程私有 * @param t the current thread * @return the map */ ThreadLocalMap getMap(Thread t) { return t.threadLocals; } /** * 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. * 为什么是Map?因为可以new 多个ThreadLocal * map也是数组加链表,没有什么好说的 */ ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) { table = new Entry[INITIAL_CAPACITY]; int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); table[i] = new Entry(firstKey, firstValue); size = 1; //设置扩容值len*2/3 setThreshold(INITIAL_CAPACITY); } public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); } //如果数组中的i位置的第一个entry不是需要找的,遍历链表 private Entry getEntry(ThreadLocal<?> key) { int i = key.threadLocalHashCode & (table.length - 1); Entry e = table[i]; if (e != null && e.get() == key) return e; else return getEntryAfterMiss(key, i, e); } 既然ThreadLocal是线程私有的,那么子线程能获取父线程的ThreadLocal吗? 是可以的 public static void main1(String[] args) { ThreadLocal<String> threadLocal = new InheritableThreadLocal<>(); threadLocal.set("1231"); threadLocal.get(); Thread thread = new Thread(() -> { System.out.println("thread:"+threadLocal.get()); }); thread.start(); } 原理是new Thread的时候 if (parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); 会给Thread中的inheritableThreadLocals初始化,并且InheritableThreadLocal重写了getMap方法。
相关文章推荐
- 理解ThreadLocal
- ThreadLocal简单理解
- 理解ThreadLocal
- java 内存消耗以及ThreadLocal理解
- 彻底理解ThreadLocal
- 理解ThreadLocal
- ThreadLocal理解
- 正确理解ThreadLocal
- 正确理解ThreadLocal
- 理解ThreadLocal
- 理解ThreadLocal(转)
- 正确理解ThreadLocal
- ThreadLocal源码理解
- ThreadLocal理解
- 深入理解threadlocal
- 正确理解ThreadLocal
- 彻底理解ThreadLocal
- volatile和ThreadLocal的理解
- 【JAVA秒会技术之多线程】彻底理解ThreadLocal
- 彻底理解ThreadLocal