摘要:下來我們來看中的方法。從中可以看到真正保存的是在中,接著看看的源碼。數(shù)組的初始長度為,最多可保存一旦超過就進(jìn)行擴(kuò)容增加一倍。而內(nèi)部利用數(shù)組來保存和值的,數(shù)組的索引就是的哈希值數(shù)組的長度。
在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中創(chuàng)建了數(shù)組,利用數(shù)組來保存Entry,Entry中保存了ThreadLocal和值。數(shù)組的初始長度為16,最多可保存length/2一旦超過就進(jìn)行擴(kuò)容(增加一倍)。
所以ThreaLocal的作用是用來實(shí)現(xiàn)線程內(nèi)部的數(shù)據(jù)共享,其實(shí)現(xiàn)原理是利用線程內(nèi)部的ThreaLocalMap來保存數(shù)據(jù)。而ThreadLocalMap內(nèi)部利用數(shù)組來保存ThreadLocal和值的,數(shù)組的索引就是ThreadLocal的哈希值&(數(shù)組的長度-1)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/72114.html
摘要:雖然類名中帶有字樣,但是實(shí)際上并不是接口的子類。是弱連接接口,這意味著如果僅有指向某一類,其任然有可能被回收掉。這里使用弱連接的意義,是為了防止業(yè)務(wù)代碼中置空對(duì)象,但是由于存在連接可達(dá),所以仍然無法回收掉該對(duì)象的情況發(fā)生。 零 前期準(zhǔn)備 0 FBI WARNING 文章異常啰嗦且繞彎。 1 版本 JDK 版本 : OpenJDK 11.0.1 IDE : idea 2018.3 2 T...
摘要:在深入理解中的變量上中我們看到的引入,使得可以很方便地在多線程環(huán)境中使用局部變量。特別需要注意的是,基類的并不會(huì)屏蔽派生類中的創(chuàng)建。到此,整個(gè)源碼核心部分已經(jīng)理解的差不多了,只剩下用來執(zhí)行清除工作。 在 深入理解Python中的ThreadLocal變量(上) 中我們看到 ThreadLocal 的引入,使得可以很方便地在多線程環(huán)境中使用局部變量。如此美妙的功能到底是怎樣實(shí)現(xiàn)的?如果你...
摘要:返回索引位置的值。因?yàn)橐蕾囉陟o態(tài)成員變量的關(guān)系,所以它的肯定唯一獲取當(dāng)前線程。位置還沒有初始化第一次這個(gè),直接將放到的位置。在線程池模式下,生命周期伴隨著線程一直存在,可能出現(xiàn)內(nèi)存泄漏的情況,最好手動(dòng)調(diào)用方法。 本文原創(chuàng)地址,:jsbintask的博客(食用效果最佳),轉(zhuǎn)載請(qǐng)注明出處! 前言 ThreadLocal是jdk中一個(gè)非常重要的工具,它可以控制堆內(nèi)存中的對(duì)象只能被指定線程訪問,如...
閱讀 2919·2023-04-26 02:14
閱讀 3771·2019-08-30 15:55
閱讀 1856·2019-08-29 16:42
閱讀 2770·2019-08-26 11:55
閱讀 2856·2019-08-23 13:38
閱讀 497·2019-08-23 12:10
閱讀 1321·2019-08-23 11:44
閱讀 2826·2019-08-23 11:43