摘要:下来我们来看中的方法。从中可以看到真正保存的是在中,接着看看的源码。数组的初始长度为,最多可保存一旦超过就进行扩容增加一倍。而内部利用数组来保存和值的,数组的索引就是的哈希值数组的长度。
在Android-27中查看源码:
在Looper源码中,我们看到通过ThreadLocal的set方法来保存Looper,通过get方法来取出Looper。下来我们来看ThreadLocal中的set/get方法。
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; } void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } 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(); } private T setInitialValue() { T value = initialValue(); Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); return value; }
从中可以看到真正保存的是在Thread.threadLocals中,接着看看ThreadLocalMap的源码。
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; setThreshold(INITIAL_CAPACITY); } private void set(ThreadLocal> key, Object value) { // We don"t use a fast path as with get() because it is at // least as common to use set() to create new entries as // it is to replace existing ones, in which case, a fast // path would fail more often than not. 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)]) { ThreadLocal> k = e.get(); if (k == key) { e.value = value; return; } if (k == null) { replaceStaleEntry(key, value, i); return; } } tab[i] = new Entry(key, value); int sz = ++size; if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); }
在ThreadLcoalMap中创建了数组,利用数组来保存Entry,Entry中保存了ThreadLocal和值。数组的初始长度为16,最多可保存length/2一旦超过就进行扩容(增加一倍)。
所以ThreaLocal的作用是用来实现线程内部的数据共享,其实现原理是利用线程内部的ThreaLocalMap来保存数据。而ThreadLocalMap内部利用数组来保存ThreadLocal和值的,数组的索引就是ThreadLocal的哈希值&(数组的长度-1)。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/72114.html
摘要:虽然类名中带有字样,但是实际上并不是接口的子类。是弱连接接口,这意味着如果仅有指向某一类,其任然有可能被回收掉。这里使用弱连接的意义,是为了防止业务代码中置空对象,但是由于存在连接可达,所以仍然无法回收掉该对象的情况发生。 零 前期准备 0 FBI WARNING 文章异常啰嗦且绕弯。 1 版本 JDK 版本 : OpenJDK 11.0.1 IDE : idea 2018.3 2 T...
摘要:在深入理解中的变量上中我们看到的引入,使得可以很方便地在多线程环境中使用局部变量。特别需要注意的是,基类的并不会屏蔽派生类中的创建。到此,整个源码核心部分已经理解的差不多了,只剩下用来执行清除工作。 在 深入理解Python中的ThreadLocal变量(上) 中我们看到 ThreadLocal 的引入,使得可以很方便地在多线程环境中使用局部变量。如此美妙的功能到底是怎样实现的?如果你...
摘要:返回索引位置的值。因为依赖于静态成员变量的关系,所以它的肯定唯一获取当前线程。位置还没有初始化第一次这个,直接将放到的位置。在线程池模式下,生命周期伴随着线程一直存在,可能出现内存泄漏的情况,最好手动调用方法。 本文原创地址,:jsbintask的博客(食用效果最佳),转载请注明出处! 前言 ThreadLocal是jdk中一个非常重要的工具,它可以控制堆内存中的对象只能被指定线程访问,如...
阅读 2901·2023-04-26 02:14
阅读 3750·2019-08-30 15:55
阅读 1842·2019-08-29 16:42
阅读 2756·2019-08-26 11:55
阅读 2844·2019-08-23 13:38
阅读 480·2019-08-23 12:10
阅读 1308·2019-08-23 11:44
阅读 2789·2019-08-23 11:43