ThreadLocal原始碼分析

2021-08-20 22:30:49 字數 4027 閱讀 5545

threadlocal使用的常見場景

1)登入使用者資訊的存放 usercontext持有乙個threadlocal

2)框架中 事務需要將connection放入threadlocal 保證多個(dao或者service操作)被外層的service的時候使用同乙個connection達到事務效果

3)spring cloud的sleuth存放span,traceid等

總體來說就是同乙個執行緒內,可以用threadlocal來傳遞變數,而無需額外的方法引數。

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

塞入thread的成員threadlocal這個map 鍵值對 key為threadlocal自身,value為變數

這樣一來執行緒thread就將 threadlocal和變數放入到自己的成員中 所以安全了

因為每個執行緒都有乙個threadlocal的內部類threadlocalmap 所以安全

估計這點跟大家想的不太一樣,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 先看第乙個

構造方法內部 (也就是建立子執行緒的時候),將thread的第二個成員進行複製給子執行緒 用處後邊會說!!

在回憶之前的threadlocal#set方法

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的鍵值對

inheritablelocal#set(val) 實際在thread.inheritablethreadlocal(第二個threadlocal的內部類threadlocalmap 成員)這個map 放置key=this value=val的鍵值對

建立子執行緒的時候即new thread()構造方法內部 將thread.inheritablethreadlocal成員複製了乙份到子執行緒 ,所以子執行緒能獲取到父執行緒的成員了

web應用像web伺服器tomcat等內部都持有乙個threadpool 執行緒已經建立好了

特別想登陸這樣的功能,不能只是往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...