ThreadLocal的作用
ThreadLocal是為了隔離多個(gè)線程的數(shù)據(jù)共享失乾。每個(gè)線程擁有自己的對(duì)象纬乍,不會(huì)和其他線程發(fā)生數(shù)據(jù)競(jìng)爭(zhēng)。
另外纽竣,它們之間也不應(yīng)該發(fā)生數(shù)據(jù)競(jìng)爭(zhēng)诅蝶,因?yàn)榧热皇褂昧薚hreadLocal,說(shuō)明每個(gè)線程都有自己的數(shù)據(jù),并且和其他的線程不同舱馅。
所以,ThreadLocal并不是為了解決數(shù)據(jù)競(jìng)爭(zhēng)的問(wèn)題棘钞,解決數(shù)據(jù)競(jìng)爭(zhēng)是指用同步、鎖等來(lái)協(xié)調(diào)多個(gè)線程對(duì)同一個(gè)數(shù)據(jù)的訪問(wèn)宜猜,而使用ThreadLocal時(shí)硝逢,每個(gè)線程存儲(chǔ)的是不同的數(shù)據(jù)绅喉。
它只是能夠在不同的線程下柴罐,通過(guò)同一個(gè)ThreadLocal訪問(wèn)到各自的數(shù)據(jù)憨奸。
ThreadLocal的方法
public ThreadLocal()
protected T initialValue()
// 初始化值。一般可以擴(kuò)展 ThreadLocal類似芝,并重載該方法板甘。默認(rèn)為 null。
public T get()
public void set(T value )
public void remove ()
ThreadLocal的實(shí)現(xiàn)原理
首先麻诀,每個(gè)線程中有一個(gè)ThreadLocalMap類型的成員變量threadLocals傲醉。
threadLocals的key為ThreadLocal,值為該線程對(duì)應(yīng)的值呻引。
所以吐咳,每個(gè)線程的值保存在線程內(nèi)部,而不是ThreadLocal中韭脊。
ThreadLocal的作用場(chǎng)景
ThreadLocal經(jīng)常作為private static變量。
當(dāng)它所在的類需要被多個(gè)線程使用饥伊,而每個(gè)線程使用各自的數(shù)據(jù)時(shí)蔫饰,應(yīng)該使用ThreadLocal。
ThreadLocal可能引發(fā)的內(nèi)存泄漏
static class ThreadLocalMap {
static class Entry extends WeakReference <ThreadLocal<?>>
{
/** The value associated with this ThreadLocal. */
Object value ;
Entry (ThreadLocal<?> k, Object v ) {
super(k );
value = v;
}
}
首先茫因,可以看到冻押,Entry擴(kuò)展WeakReference驰贷,其中Key為WeakReference饱苟,而Value為強(qiáng)引用狼渊。
![](http://img0.ph.126.net/kySwe5ze1tHKNZSmV3WU9A==/6631337146049824986.png)
所以,當(dāng)ThreadLocal沒(méi)有外部強(qiáng)引用時(shí)城须,當(dāng)系統(tǒng)gc時(shí)米苹,ThreadLocal會(huì)被回收,key為null良瞧,那么對(duì)應(yīng)的value就不能被訪問(wèn)训唱,也不會(huì)被釋放(除非Thread被銷毀)。
但是况增,ThreadLocalMap的實(shí)現(xiàn)中,有一些避免內(nèi)存泄漏的方法歧强。
在調(diào)用ThreadLocal的get或set方法時(shí)为肮,會(huì)根據(jù)hashcode尋找key的位置,在尋找的過(guò)程中丧靡,如果發(fā)現(xiàn)key為null籽暇,而value不為null戒悠,會(huì)釋放value的強(qiáng)引用舟山。
當(dāng)然卤恳,在不能保證不存在內(nèi)存泄漏寒矿,所以在不用時(shí),調(diào)用ThreadLocal的remove方法來(lái)防止內(nèi)存泄漏拆融。
參考
[Java并發(fā)包學(xué)習(xí)七]解密ThreadLocal
Java并發(fā)編程:深入剖析ThreadLocal