四、總結
一、背景
因為需要,研究了可以通過inheritablethreadlocal
進行父子執行緒中如何傳遞本地執行緒變數,通過阿里開源專案transmitablethreadlocal
進行進行執行緒池傳遞本地執行緒變數(詳解可檢視以往部落格)。在查詢資料的過程中無意發現了dobbo
的internalthreadlocal
,其實dobbo
的internalthreadlocal
和netty
的fastthreadlocal
有異曲同工之妙。之前學netty
的時候有了解一點,為了加深一下threadlocal
種群的了解,使用本部落格記錄一下。
二、例項
public
static
void
main
(string[
] args)})
.start()
;/**
* fastthreadlocalthread執行緒呼叫方式
*/newfastthreadlocalthread
(new
runnable()
}).start()
;}
單從執行結果看,都能獲取到對應設定的值,二者沒有任何輸出區別,但是跟蹤一下,可以看到呼叫的邏輯是有所區別的。
三、原理
熟悉threadlocal
的應該知道,threadlocal
其實內部邏輯是乙個以threadlocal
物件為key
,需要儲存的值為value
的map
結構。而fastthreadlocal
的內部實現是乙個陣列,實現上是直接通過下標定位元素,所以單純從取、存的角度看,fastthreadlocal
是比threadlocal
高效。
對於使用原生執行緒thread
來說,其實最後是將資料存thread.threadlocals(threadlocal.threadlocalmap)
中,也就是說在這個執行緒所使用的所有fastthreadlocal
最後都以key=threadlocal
fastthreadlocalthread
是直接繼承於執行緒類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.removepublic
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...