threadlocal原始碼解讀

2022-01-22 01:46:05 字數 1724 閱讀 7584

時間過得真快,轉眼之間已經畢業半年多了,上次從寫東西還是剛學springboot的時候,後來就再也沒有更新過,然而現在springcloud都會用了.

話不多說開始正題,最近最看併發的一些東西 而且正好趕上 公司裡抽到我分享技術,於是就分享了下threadlocal。

threadlocalmap是threadlocal裡面的靜態內部類 核心也是這個map 今天解析的就是這個map 其餘的比如說thread的get set過程大家有興趣可以去看一下,其實也是呼叫的threadlocalmap中的原始碼。

一.thradlocalmap,thread,threadlocal關係

在講核心內容之前 我先給大家普及一下這三者的關係,threadlocalmap是thread中的成員變數,同時也是threadlocal中的靜態內部類,見下圖

二.資料結構

threadlocalmap中維護乙個entry陣列,entry中的key其實是threadloacl的弱引用,value就是value,如下圖:

大家可以看到 我們的entry節點 繼承了弱引用這個類 並且在構造中通過super呼叫父類將我們的threadlocal引用包裹了起來,value沒做處理 直接賦值.那麼作者為什麼要用弱引用呢?如果要是強引用的話那麼 引用的threadlocal物件被置為null的話 我們的threadlocalmap還持有這個物件的強引用如果沒有手動刪除那麼肯定不會自我清理的,但是弱引用的話 就不會這樣的 因為一旦是弱引用的 一般下次gc entry鍵會被**,這個entry就失效了,我們這個threadlocal就可以進行自己的垃圾清理機制了,因為我們的threadlocalmap跟thread的生命週期一樣長,同樣的條件下明顯 弱引用相當於多了一層保障。

三.怎樣解決雜湊衝突

theadlocalmap中解決雜湊衝突的辦法是開放定址法,言簡意賅就是發生雜湊衝突的話,去尋找沒有被占用的位置進行插入,去尋找位置是有方法的而不是沒有目的的盲目去尋找,這個方法我們叫做探查方法,開放定址法的探查方法有三種,一是線性探查,二是二次探查,三是雙重雜湊,雙重雜湊是探查方法中最好的,因為它找的位置足夠隨機,沒有那麼嚴重的群集問題 其次是二次探查 ,最後才是線性探查,有興趣的同學可以自行查詢學習下,在這裡我其實一直有乙個疑問那為什麼我們的threadlocalmap解決雜湊衝突使用的是線性探查 而不是雙重雜湊????

四.set

第一步開始線性探查 要是探測過程中命中了就將value替換掉,如果探測過程中發現有位置是失效(位置1)的了 那麼就開始從這個位置向前找查詢最前面乙個失效的位置(位置2),然後從這個失效位置(位置1)向後遍歷table,如果在向後遍歷的過程中命中了那麼就將entry替換到位置1,而這個位置恰巧就是之前找到的最前面的那個失效的位置(位置2)的話,那麼就以這個位置進行清理,如果不是的話 那麼以最前面的那個失效的位置(位置2)進行清理,其實就是沒有命中的話 一定會將這個k,v替換到沒有命中的那個失效得位置(位置1)上,如果在向後的探測中並沒有命中key那麼就new乙個entry將這個失效的位置(位置1)替換掉,要是探測過程中沒有發現失效的 也沒有命中 那麼就在entry陣列最後在新新增乙個。

五.getentry

getentry相比於set方法來說 簡單太多了 

一上來要是直接找到的話 那麼直接返回這個entry,沒有找到的話進行就開始向後探測這個entry 因為向後探測 還是有可能找到的。如果再向後探測過程中 如果·發現有 失效的entry 將這個失效的位置清理掉 陣列長度 減一,並且將從這個位置開始 向後尋找最後乙個空位置,在這個區間將所有失效的entry都清除掉。

ThreadLocal原始碼理解

threadlocal其實原理是建立了多份相同資料儲存在堆記憶體上,每個執行緒的thread類裡有threadlocal.threadlocalmap threadlocals的屬性來指向存位置,所以每個執行緒修改都不會影響到其他執行緒的資料 首先說下下面用到的東西 threadlocalmap為t...

ThreadLocal原始碼分析

在理解handler looper之前,先來說說threadlocal這個類,聽名字好像是乙個本地執行緒的意思,實際上它並不是乙個thread,而是提供乙個與執行緒有關的區域性變數功能,每個執行緒之間的資料互不影響。我們知道使用handler的時候,每個執行緒都需要有乙個looper物件,那麼and...

ThreadLocal 原始碼解讀

在正式讀 前先簡單介紹threadlocal的實現方式。每個執行緒都會有乙個threadlocalmap,只有在使用到threadlocal的時候才會初始化threadlocalmap。需要儲存的物件t會被放到entry裡面儲存在threadlocalmap的陣列中,entry是乙個鍵值對的資料結構...