13.3 ThreadLocal
在多線程環(huán)境下,每個(gè)線程都有自己的數(shù)據(jù)。一個(gè)線程使用自己的局部變量比使用全局變量好,因?yàn)榫植孔兞恐挥芯€程自己能看見,不會(huì)影響其他線程,而全局變量的修改必須加鎖。
但是局部變量也有問題,就是在函數(shù)調(diào)用的時(shí)候,傳遞起來很麻煩:
每個(gè)函數(shù)一層一層調(diào)用都這么傳參數(shù)那還得了?用全局變量?也不行,因?yàn)槊總€(gè)線程處理不同的Student
對(duì)象,不能共享。
如果用一個(gè)全局dict
存放所有的Student
對(duì)象,然后以thread
自身作為key
獲得線程對(duì)應(yīng)的Student
對(duì)象如何?
這種方式理論上是可行的,它最大的優(yōu)點(diǎn)是消除了std
對(duì)象在每層函數(shù)中的傳遞問題,但是,每個(gè)函數(shù)獲取std
的代碼有點(diǎn)丑。
有沒有更簡(jiǎn)單的方式?
ThreadLocal
應(yīng)運(yùn)而生,不用查找dict
,ThreadLocal
幫你自動(dòng)做這件事:
執(zhí)行結(jié)果:
全局變量local_school
就是一個(gè)ThreadLocal
對(duì)象,每個(gè)Thread
對(duì)它都可以讀寫student
屬性,但互不影響。你可以把local_school
看成全局變量,但每個(gè)屬性如local_school.student
都是線程的局部變量,可以任意讀寫而互不干擾,也不用管理鎖的問題,ThreadLocal
內(nèi)部會(huì)處理。
可以理解為全局變量local_school
是一個(gè)dict
,不但可以用local_school.student
,還可以綁定其他變量,如local_school.teacher
等等。
ThreadLocal
最常用的地方就是為每個(gè)線程綁定一個(gè)數(shù)據(jù)庫(kù)連接,HTTP請(qǐng)求,用戶身份信息等,這樣一個(gè)線程的所有調(diào)用到的處理函數(shù)都可以非常方便地訪問這些資源。
小結(jié)
一個(gè)ThreadLocal
變量雖然是全局變量,但每個(gè)線程都只能讀寫自己線程的獨(dú)立副本,互不干擾。ThreadLocal
解決了參數(shù)在一個(gè)線程中各個(gè)函數(shù)之間互相傳遞的問題。