threadlocal使用的常見場景
1)登入使用者資訊的存放 usercontext持有乙個threadlocal總體來說就是同乙個執行緒內,可以用threadlocal來傳遞變數,而無需額外的方法引數。2)框架中 事務需要將connection放入threadlocal 保證多個(dao或者service操作)被外層的service的時候使用同乙個connection達到事務效果
3)spring cloud的sleuth存放span,traceid等
public
class
loginmembercontext
private
static threadlocal
loginthreadlocal =
newthreadlocal
<
>()
;public
static
void
set(loginmembermodel loginmembermodel)
public
static loginmembermodel get()
public
static
void
clear()
}
登入***塞入threadlocal
public
class
loginhandlerinterceptor
implements
handlerinterceptor
loginmembermodel.
settoken
(token)
; loginmembercontext.
set(loginmembermodel);}
}
在controller中使用
@restcontroller
("/right"
)public
class
rightindexcontroller
/index"
)public apiresult
index
(@pathvariable string citycode)
}
如何理解變數和執行緒繫結
不看原始碼第一印象可能就是
threadlocal中有乙個map成員 set就是講thread作為key value就是value哈!!!有沒有中槍??然並卵。
public
class
threadlocal
public
void
set(t value)
public t get()
void
createmap
(thread t, t firstvalue)
static threadlocalmap createinheritedmap
(threadlocalmap parentmap)
}
內有有乙個內部類 threadlocalmap 類似於map結構幾個核心方法方法內部去沒有直接使用被thread類持有(引用)
threadlocal#set方法【使用的是thread.threadlocal屬性】
public
void
set(t value)
//可以被子類重寫!!!
threadlocalmap getmap
(thread t)
void
createmap
(thread t, t firstvalue)
set方法是指就是 初始化thread.threadlocal成員 它是threadlocal的內部類threadlocalmap 類似於map因為每個執行緒都有乙個threadlocal的內部類threadlocalmap 所以安全塞入thread的成員threadlocal這個map 鍵值對 key為threadlocal自身,value為變數
這樣一來執行緒thread就將 threadlocal和變數放入到自己的成員中 所以安全了
估計這點跟大家想的不太一樣,threadlocal裡邊的map 是被執行緒持有 當呼叫theadlocal#set方法的時候
實際是往thread.threadlocal這個map中塞入的值 key是threadloca本身 value是變數
方案就是使用 threadlocal的子類 inheritablethreadlocal
再次之前看下thread類的原始碼
執行緒thread類 持有threadlocal的內部類threadlocalmap
public
class
thread
implements
runnable
//這裡暫時已列出來 這個跟第二個成員 inheritablethreadlocals有關係
}//在否早方法中執行的 也就是建立子執行緒的時候拷貝thread的第二個成員到子執行緒的第二個成員 有什麼用 後邊說!
init
(***)
}
執行緒持有內部有兩個成員 都是threadlocal的內部類threadlocalmap 先看第乙個在回憶之前的threadlocal#set方法構造方法內部 (也就是建立子執行緒的時候),將thread的第二個成員進行複製給子執行緒 用處後邊會說!!
public
void
set(t value)
//可以被子類重寫!!!
threadlocalmap getmap
(thread t)
void
createmap
(thread t, t firstvalue)
實際上inheritablethreadlocal將getmap和createmap重寫了
public
class
inheritablethreadlocal
extends
threadlocal
threadlocalmap getmap
(thread t)
void
createmap
(thread t, t firstvalue)
}
總結下:
threadlocal#set(val)實際是在thread.threadlocal(第乙個threadlocal的內部類threadlocalmap 成員)這個map 放置key=this value=val的鍵值對web應用像web伺服器tomcat等內部都持有乙個threadpool 執行緒已經建立好了inheritablelocal#set(val) 實際在thread.inheritablethreadlocal(第二個threadlocal的內部類threadlocalmap 成員)這個map 放置key=this value=val的鍵值對
建立子執行緒的時候即new thread()構造方法內部 將thread.inheritablethreadlocal成員複製了乙份到子執行緒 ,所以子執行緒能獲取到父執行緒的成員了
特別想登陸這樣的功能,不能只是往threadlocal#set 執行緒是復用的第二個請求也會執行threadloca#set
如果不進行清理的話,thread.threadlocal這個map中的鍵值對會越來越多導致記憶體洩漏 oom
在合適的地方一定執行clear操作
ThreadLocal實現原理與原始碼分析
threadlocal底層實現內部類 threadlocalmap 一 threadlocal的set方法原始碼分析 1 public void set t value thread t thread.currentthread threadlocalmap map getmap t if map ...
ThreadLocal原始碼理解
threadlocal其實原理是建立了多份相同資料儲存在堆記憶體上,每個執行緒的thread類裡有threadlocal.threadlocalmap threadlocals的屬性來指向存位置,所以每個執行緒修改都不會影響到其他執行緒的資料 首先說下下面用到的東西 threadlocalmap為t...
ThreadLocal原始碼分析
在理解handler looper之前,先來說說threadlocal這個類,聽名字好像是乙個本地執行緒的意思,實際上它並不是乙個thread,而是提供乙個與執行緒有關的區域性變數功能,每個執行緒之間的資料互不影響。我們知道使用handler的時候,每個執行緒都需要有乙個looper物件,那麼and...