本地執行緒變數(四) FastThreadLocal

2021-10-25 08:08:17 字數 4055 閱讀 1253

四、總結

一、背景

​ 因為需要,研究了可以通過inheritablethreadlocal進行父子執行緒中如何傳遞本地執行緒變數,通過阿里開源專案transmitablethreadlocal進行進行執行緒池傳遞本地執行緒變數(詳解可檢視以往部落格)。在查詢資料的過程中無意發現了dobbointernalthreadlocal,其實dobbointernalthreadlocalnettyfastthreadlocal有異曲同工之妙。之前學netty的時候有了解一點,為了加深一下threadlocal種群的了解,使用本部落格記錄一下。

二、例項

public

static

void

main

(string[

] args)})

.start()

;/**

* fastthreadlocalthread執行緒呼叫方式

*/newfastthreadlocalthread

(new

runnable()

}).start()

;}

單從執行結果看,都能獲取到對應設定的值,二者沒有任何輸出區別,但是跟蹤一下,可以看到呼叫的邏輯是有所區別的。

三、原理

​ 熟悉threadlocal的應該知道,threadlocal其實內部邏輯是乙個以threadlocal物件為key,需要儲存的值為valuemap結構。而fastthreadlocal的內部實現是乙個陣列,實現上是直接通過下標定位元素,所以單純從取、存的角度看,fastthreadlocal是比threadlocal高效。

​ 對於使用原生執行緒thread來說,其實最後是將資料存thread.threadlocals(threadlocal.threadlocalmap)中,也就是說在這個執行緒所使用的所有fastthreadlocal最後都以key=threadlocalfastthreadlocalthread是直接繼承於執行緒類thread,並且內部維護乙個internalthreadlocalmap,用於儲存變數。雖然這個類命名為map,結構上其實是乙個陣列。並且下標為0的元素是乙個set>的結構,儲存著當前有效的fastthreadlocal

public

class

fastthreadlocalthread

extends

thread

internalthreadlocalmap中提供了一些靜態方法,通過當前執行緒的不同型別,以不同的方式獲取對應所需要的internalthreadlocalmap

/**

* 獲取方法

*/public

static internalthreadlocalmap get()

else

}/**

* fastthreadlocalthred獲取方法

*/private

static internalthreadlocalmap fastget

(fastthreadlocalthread thread)

return threadlocalmap;

}/**

* 原生執行緒的獲取方法

*/private

static internalthreadlocalmap slowget()

return ret;

}

1.set值
public

final

void

set(v value)

else

}public

final

void

set(internalthreadlocalmap threadlocalmap, v value)

}else

}private

static

void

addtovariablestoremove

(internalthreadlocalmap threadlocalmap,

fastthreadlocal<

?> variable)

else

// 新增元素到set集合中

variablestoremove.

add(variable)

;}

2.get值
public

final v get()

/** * get操作比較簡單,直接從threadlocalmap獲取對應的下標元素返回。

*/public

final v get

(internalthreadlocalmap threadlocalmap)

return

initialize

(threadlocalmap);}

/** * 是乙個預設值操作,可以通過最後的initvalue()會呼叫fastthreadlocal#initialvalue

* 做乙個初始化的操作。

*/private v initialize

(internalthreadlocalmap threadlocalmap)

catch

(exception e)

threadlocalmap.

setindexedvariable

(index, v)

;addtovariablestoremove

(threadlocalmap,

this);

return v;

}

3.remove
public

final

void

remove()

@suppresswarnings

("unchecked"

)public

final

void

remove

(internalthreadlocalmap threadlocalmap)

// 刪除對應下標值,賦值為unset佔位符

object v = threadlocalmap.

removeindexedvariable

(index)

;//刪除internalthreadlocalmap[0]的set>中的當前fastthreadlocal物件

removefromvariablestoremove

(threadlocalmap,

this);

if(v != internalthreadlocalmap.unset)

catch

(exception e)

}}

四、總結

fastthreadlocal實際上採用的是陣列的方式進行儲存資料,在資料的獲取、賦值都是通過下標的方式進行,而threadlocal是通過map結構,先計算雜湊值,在進行線性探測的方式進行定位。所以在高併發下,fastthreadlocal應該相對高效,但是fastthread有乙個弊端就是index是一直累加,也就是說如果移除了某個變數是通過將對應下標的元素標記為unset佔位,而不進行**,會無限制增大,會觸發擴容等一些問題。

Python 本地執行緒

import threading import time class a pass a a deffunc num a.name num time.sleep 1 print a.name,threading.current thread name 結果d virtualenv envs vuedj...

flask本地執行緒與Local

1.我在寫乙個部落格 的時候,當乙個使用者註冊了賬號資訊的時候會傳送一封郵件到郵箱讓使用者來確認,我發現其中有乙個問題就是當請求來時一次只能傳送一封郵件,所以在傳送多封郵件時會耗費很多的時間,這時候就需要多執行緒技術,當然了在處理http請求的伺服器也是這樣的,當我們自己寫的程式在面臨大量的使用者同...

flask 本地執行緒 請求上下文補充

context 上下文 是flask裡面非常好的設計,使用flask需要非常理解應用上下文和請求上下文這兩個概念 本地執行緒 本地執行緒的實現原理就是 在threading.current thread dict 裡新增乙個包含物件mydata的id值的key,來儲存不同的執行緒狀態werkzeug...