本文分析threadlocal的原理和使用多執行緒訪問共享變數時容易出現併發問題,為了保證執行緒安全,一般會給共享變數進行適當的加鎖同步。如果不想加鎖呢?
threadlocal可以做到執行緒隔離,多個執行緒訪問共享變數時,訪問的是自己執行緒的變數。
threadlocal提供了執行緒本地變數,如果建立了乙個threadlocal變數,那麼訪問這個變數的每個執行緒都會有這個變數的乙個本地副本,當多執行緒操作這個變數時,實際操作的是自己本地記憶體的變數,從而避免執行緒安全的問題。
public
class
threadlocaldemo},
"i am thread --"
+i);
thread.
start()
;}}}
執行結果
thread類中有兩個包訪問變數,乙個是threadlocals ,乙個是inheritablethreadlocals,它們都是threadlocalmap型別的變數。
而threadlocalmap又是threadlocal的內部類。
預設情況下,每個執行緒的這兩個變數都為null,只有當執行緒第一次呼叫threadlocal 的set 或者get方法時才會建立他們。
每個執行緒的本地變數是存在呼叫執行緒的threadlocals變數中的,threadlocal通過set方法把value放在呼叫執行緒的threadlocals變數中,通過get方法取出呼叫執行緒的threadlocals中的值。
thread裡面的threadlocals為何設計為map結構?因為每個執行緒可以關聯多個threadlocal變數。
下面分析下 threadlocal 的set、get及remove方法
1.set
public
void
set(t value)
threadlocalmap getmap
(thread t)
void
createmap
(thread t, t firstvalue)
//threadlocalmap的建構函式
threadlocalmap
(threadlocal<
?> firstkey, object firstvalue)
2.get
public t get()
}return
setinitialvalue()
;}private t setinitialvalue()
remove
public
void
remove()
private
void
remove
(threadlocal<
?> key)
}}
threadlocalmap內部類 enrtry
static
class
entry
extends
weakreference
?>>
}
enrtry 繼承自軟引用,當對應的threadlocal物件為null時,此entry物件會被jvm**,避免出現記憶體洩漏。
也就是說,同乙個threadlocal變數在父執行緒中被設定值後,在子執行緒中是獲取不到的。
利用inheritablethreadlocal類,子執行緒可以訪問父執行緒中的本地變數。
//繼承threadlocal類
public
class
inheritablethreadlocal
extends
threadlocal
//返回當前執行緒的inheritablethreadlocals變數
threadlocalmap getmap
(thread t)
//初始化當前執行緒的inheritablethreadlocals變數
void
createmap
(thread t, t firstvalue)
}
當子執行緒初始化時會判斷父執行緒的inheritablethreadlocals變數是否為null,不為null 則會賦值給子執行緒inheritablethreadlocals變數
}改為inheritablethreadlocal 執行
深入了解A
一 前言 在這裡我將對a 演算法的實際應用進行一定的 並且舉乙個有關a 演算法在最短路徑搜尋的例子。值得注意的是這裡並不對a 的基本的概念作介紹,如果你還對a 演算法不清楚的話,請看姊妹篇 初識a 演算法 這裡所舉的例子是參考amit主頁中的乙個源程式,使用這個源程式時,應該遵守一定的公約。二 a ...
深入了解A
一 前言 在這裡我將對a 演算法的實際應用進行一定的 並且舉乙個有關a 演算法在最短路徑搜尋的例子。值得注意的是這裡並不對a 的基本的概念作介紹,如果你還對a 演算法不清楚的話,請看姊妹篇 初識a 演算法 這裡所舉的例子是參考amit主頁中的乙個源程式,使用這個源程式時,應該遵守一定的公約。二 a ...
深入了解Dojo Data
譯自http www.sitepen.com blog 2010 10 13 dive into dojo data 使用dojo data有助於快速建立web應用的介面,且易於嵌入各種資料來源。它在使用者介面與底層資料之間提供了一層抽象層,使得使用者介面開發人員能夠專注於ui的開發,而無需擔心資料...