1. 程式人生 > >執行緒區域性變數ThreadLocal的簡單使用

執行緒區域性變數ThreadLocal的簡單使用

今天來說說ThreadLocal的使用:

什麼是ThreadLocal:ThreadLocal是執行緒區域性變數,所謂的執行緒區域性變數,就是僅僅只能被本執行緒訪問,不能線上程之間進行共享訪問的變數。在各個Java web的各種框架中ThreadLocal幾乎已經被用爛了,spring中有使用,mybatis中也有使用,hibernate中也有使用,甚至我們寫個分頁也用ThreadLocal來傳遞引數......這也從側面說明了ThreadLocal十分的給力。

下面看看作者Doug Lea是怎麼說的,下面是jdk7.X中的註釋:

  1. 也就是說這個類給執行緒提供了一個本地變數,這個變數是該執行緒自己擁有的。在該執行緒存活和ThreadLocal例項能訪問的時候,儲存了對這個變數副本的引用.當執行緒消失的時候,所有的本地例項都會被GC。並且建議我們ThreadLocal最好是 private static 修飾的成員

  2. ThreadLocal和Synchonized區別:

    都用於解決多執行緒併發訪問。

    Synchronized用於執行緒間的資料共享(使變數或程式碼塊在某一時該只能被一個執行緒訪問),是一種以延長訪問時間來換取執行緒安全性的策略;

    而ThreadLocal則用於執行緒間的資料隔離(為每一個執行緒都提供了變數的副本),是一種以空間來換取執行緒安全性的策略。

  3. ThreadLocal的簡單方法:

    ThreadLocal有兩個簡單的方法,一個set()方法,一個get()方法

    簡單程式碼應用(由於頭條不儲存程式碼格式,在這裡我就直接上圖片了,大家湊合著看):

ThreadLocalTest類有兩個方法,一個是start方法,一個是end方法,start記錄開始時間,end方法記錄結束時間,這個方法可以簡單的用在統計耗時的功能上,在方法的入口前執行start,在方法被呼叫之後呼叫end方法,好處是兩個方法的呼叫不用再一個方法或者類中,比如在aop(面向切面程式設計)中,在方法呼叫前的切入點執行start方法,在方法呼叫之後呼叫end方法,這樣依舊可以得到方法執行的耗時。

好,上邊是簡單的應用,下面我從原始碼的角度給大家分析一下ThreadLocal:

如果讓我自己想辦法的話我會將Thread和value放在一個map中,這樣我們get的時候直接get(Thread)就行了,但是我們通過原始碼看看ThreadLocal是怎麼做的:

我們看到,這裡聲明瞭一個ThreadLocalMap,我們在看getMap方法是怎麼實現的:

我們看到,是返回了一個成員變數,到這貌似有了點頭緒,是把ThreadMap和Thread綁了起來。

這個threadLocals是哪裡來的呢?

看,是ThreadLocal幫助Thread聲明瞭該欄位。

如果是第一次呼叫的話ThreadLocalMap是為null的,我們在來看看createMap方法是怎麼實現的:

在這裡new了一個ThreadLocalMap,引數是this(就是這個執行緒),另一個是value,在往下看new ThreadLocalMap是怎麼new 的:

看到這裡就明朗了,ThreadLocalMap中的引數是ThreadLocal,並不是Thread,這就和我想的思路有差異了。

總結:就是在Thread中有一個類似於Map的東西,並且預設為空,在我們聲明瞭ThreadLocal的時候,ThreadLocal把這個Map初始化了,並且把ThreadLocal和value繫結到了這個map中,也就是說這個map的key值是ThreadLocal,但是我在剛開始想的是將Thread當做key這樣做到底有什麼好處呢?

優點1:這樣做把value放在了執行緒當中,這樣執行緒死亡,value隨之回收,而原來的方式沒有放線上程中,Thread死亡的時候value不確定是不是回收,所以這個改進更加人性化了。以為value定義的初衷就是屬於Thread的

優點2:效能提升了,想一想,如果按照原來的方法,把整個Thread放入到map中的話,如果放入的執行緒很多的話,這個map肯定會很大的,說白了就是Thread佔用的空間>ThreadLocal佔用的空間,空間大了,map在get的時候效能肯定是會下降的。

以上兩點是我淺顯的理解,可能有不足的地方,如果哪位大神覺得我說的有問題的話,歡迎指出來,小編虛心接受;

好了,以上就是簡單總結的ThreadLocal的簡單總結,原始碼的話還有別的原始碼,我沒有列舉所有,大家感興趣的話可以自己去看看。如果覺得我的文章對你有幫助,請關注我,後續會有更好的文章,謝謝大家。