ThreadLocal工作原理 部分原始碼分析

2023-01-07 08:48:06 字數 2643 閱讀 7728

1.大概去**看

threadlocal 其根本實現方法,是在thread裡面,有乙個屬性

threadlocals = null;

threadlocalmap 靜態內部類維護了乙個entry 陣列

1private entry table;

檢視entry 原始碼,它維護了兩個屬性,threadlocal 物件與乙個object

複製**

static class entry extends weakreference>

複製**

那麼,這幾項似乎可以這麼串下來: thread. currentthread().

threadlocals. table{當前執行緒,的threadlocalmap物件,的entry陣列}(忽略訪問許可權的事兒)

我是分割線

2.**實現分析

threadlocal 提供set(),get()方法,用於資料的寫入與讀取。資料的儲存與獲取的位置,即

thread. currentthread().threadlocals. table {當前執行緒,的threadlocalmap物件,的entry陣列}

複製**

public void set(t value)

複製**

value);注意,這裡,傳入的第乙個引數為this 即 threadlocal 物件自身,

假如我們宣告了一串**:

1private static threadlocal threadlocal = new threadlocal();

然後我們又執行了 1234」);

那麼,在thread. currentthread().threadlocals.

table 中,應該有這麼乙個entry :threadlocal指向threadlocal,value 為 「string 1234」

分析原始碼(這裡,所有的原始碼都來自於jdk1.7.0_71):

複製**

private void set(threadlocal<?> key, object value)

複製**

分析兩處:

1. int i = & (len-1);

根據當前的threadlocal 的threadlocalhashcode 跟 的長度-1 ,按位與,獲得目標索引值 i , 如果tab[i] 為空的話,將會在 tab[i] 處插入乙個entry ;

2. for (entry e = tab[i]; e != null; e = tab[i = nextindex(i, len)])

如果如果tab[i] 不為空,則呼叫i = nextindex(i, len) 將i值進行+1或者置為0,然後判斷e是否為null 如果e!=null 判斷e 中的 threadlocal物件,跟傳入的threadlocal 物件,是否為同乙個物件。如果是同乙個物件,則對e的value 進行重新賦值。

如果在遍歷的過程中發現某個e的threadlocal 物件為空,則將entry(threadlocal,」 string 1234」) 設定在此時的tab[i]處。

(如果一開始進來的時候e 為null 即 tab[i]==null 。是不會走for迴圈的,會直接把entry(threadlocal,」 string 1234」) 賦值到table[i]);12

3private static int nextindex(int i, int len)

分析,為什麼會有i = nextindex(i, len) 這樣的設定。

執行int i = & (len-1);的時候,很可能不同的得到了相同的 i 值,那麼,就從 i 開始,遍歷table物件,找到乙個可以放置entry(threadlocal,」 string 1234」) 的位置,

比如: & 16-1);//5

& 16-1);//5

& 16-1);//5

這三個,獲取到的i值,都為5(當然實際用到的hashcode的演算法不是這樣的,不會產生這麼接近的數)。

在同乙個執行緒中,626627285先set(value1)了,得到5,table[5]為空,那就填進去 table[5]=new entry(626627285,value1);

626627317接著set(value2),算出來i=5,

但是table[5]已經有人佔了,那就只能看table[6]有沒有空閒位置,一看table[6]==null,好,就放這兒了table[6]=new entry(626627317,value2);

626627573接著set(value3),算出來i=5,

但是table[5]已經有人佔了,那就只能看table[6]有沒有空閒位置,一看table[6]也被佔了,再看table[7]==null,好,就放這兒了table[7]=new entry(626627573,value3)

假如有個執行緒算出來i=15 但是table[15]!=null,需要向後找空閒位置,table[16]是越界的,nextindex返回0,從table[0]開始找

下面這串**,維護了table 的長度,避免了遍歷了一圈table 卻找不到 table[i]==null 的情況,即保證table的某些索引處肯定為null,因為還沒填滿的時候就已經擴容了。

if (!cleansomeslots(i, sz) && sz >= threshold)

rehash();

我是分割線

ThreadLocal原始碼分析

一 概念 threadlocal提供執行緒本地變數。這些變數與普通變數不同,每個執行緒有自己的乙份拷貝。threadlocal例項典型用法是在類中作為私有的靜態域,用與執行緒繫結狀態 比如,使用者id或者事務id 簡而言之,每個執行緒第一次獲取該值後,之後 程內部就可以隨意操作該變數,但是這並不影響...

RAM工作原理

實際的儲存器結構由許許多多的基本儲存單元排列成矩陣形式,並加上位址選擇及讀寫控制等邏輯電路構成。當cpu要從儲存器中讀取資料時,就會選擇儲存器中某一位址,並將該位址上儲存單元所儲存的內容讀走。早期的dram的儲存速度很慢,但隨著記憶體技術的飛速發展,隨後發展了一種稱為快速頁面模式 fastpagem...

電路工作原理

該數控可調直流穩壓電源電路由穩壓電路和輸出電壓控制電路組成,如圖所示。穩壓電路由電源開關sl 電源變壓器t 整流橋堆ur 電容器cl c3 三端穩壓積體電路icl ic3和電阻器ro rlo等組成。輸出電壓控制電路由控制按鈕s2 復位按鈕s3 電阻器r1l r31 電晶體vl v10 發光二極體vl...