在web開發的
session中
,不同的執行緒對應不同的
session
,那麼如何針對不同的執行緒獲取對應的
session
呢?我們可以設想了如下兩種方式:
1.在action中建立
session
,然後傳遞給
service
,service
再傳遞給
dao,很明顯,這種方式將使**變得臃腫複雜。
2.建立乙個靜態的map,鍵對應我們的執行緒,值對應
session
,當我們想獲取
session
時,只需要獲取
map,然後根據當前的執行緒就可以獲取對應的值。
我們看看hibernate中是如何實現這種情況的:
在hibernate中是通過使用
threadlocal
來實現的。在
getsession
方法中,如果
threadlocal
存在session
,則返回
session
,否則建立乙個
session
放入threadlocal
中。總結一下就是在
threadlocal
中存放了乙個
session
。實際上threadlocal中並沒有存放任何的物件或引用,在上面的的**中
threadlocal
的例項threadsession
只相當於乙個標記的作用。
而存放物件的真正位置是正在執行的thread執行緒物件
,每個thread物件中都存放著乙個
threadlocalmap
型別threadlocals物件
,這是乙個對映表
map,這個
map的鍵是乙個
threadlocal
物件,值就是我們想存的區域性物件。
我們以上面的**為例分析一下:
當我們往threadlocal中存放變數
的時候發生了什麼?
即這行**時。
我們看下threadlocal的原始碼中set()方法的實現。
如果把這些**簡化的話就一句
thread.currentthread().threadlocals.set(this,value);
thread.currentthread()
獲取當前的執行緒
threadlocals
就是我們上面說的每個執行緒物件中用於存放區域性物件的
map所以set()就是獲取到當前執行緒的
map然後把值放進去,我們發現鍵是
this
,也就是當前的
threadlocal
物件,可以發現
threadlocal
物件就是乙個標記的作用,我們根據這個標記找到對應的區域性物件。
如果對比get()方法,可以發現原理都差不多,都是對執行緒中的
threadlocals
這個map
的操作,我就不解釋了。
threadlocal
的set()
或者get()
方法時,其實是在操作我們執行緒自帶的
threadlocals
這個map
,多個執行緒的時候自然就有多個
map,這些
map互相獨立,但是,這些
map都是根據乙個
threadlocal
物件(因為它是靜態的)來作為鍵存放。
這樣可以在多個執行緒中,每個執行緒存放不一樣的變數,我們通過乙個threadlocal物件,在不同的執行緒(通過
thread.currentthread()獲取當前執行緒
)中得到不同的值(不同執行緒的
threadlocals
不一樣)。
為什麼threadlocals要是乙個
map呢?
因為我們可能會在乙個類中宣告多個
threadlocal
的例項,這樣就有多個標記,所以要使用
map對應。
threadlocal就是用來在類中宣告的乙個標記,然後通過這個標記就根據不同
thread
物件訪問值。
參考部落格:
ThreadLocal的個人理解
threadlocal的設計思想十分簡單,它的核心物件就是threadlocalmap,被宣告在thread類裡面,每個thread都持有乙個threadlocalmap,所以才能實現執行緒隔離,以達到儲存共享變數的作用 threadlocal.threadlocalmap threadlocals...
ThreadLocal個人理解
為了加深理解,將最近對threadlocal的了解和原始碼分析記錄總結一下。threadlocal可以為執行緒提供區域性變數。使用threadlocal的get 方法,可以在當前執行緒能夠訪問的類和方法中,得與當前執行緒相關聯的變數值。不過,執行緒區域性變數並不是由threadlocal物件儲存維護...
ThreadLocal個人理解
每乙個thread物件中有乙個threadlocalmap的map屬性 該map的key是乙個弱引用 key被weakreference物件指向 當gc時就會 該entry就會 map屬性,避免了記憶體洩漏 當使用threadlocal時,當threadlocal屬性作為map的key,將當前執行緒...