Java多執行緒之——ThreadLocal
ThreadLocal是什麼:每一個ThreadLocal能夠放一個執行緒級別的變數,也就是說,每一個執行緒有獨自的變數,互不干擾。以此達到執行緒安全的目的,並且一定會安全。
實現原理:
要了解實現原理,我們先看set方法
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
引數是我們要存的值 Object
第一步取到當前執行緒
第二步有一個方法getMap,點進去看(ps:準備好轉圈圈哦~),順便看一下Thread類的一個屬性
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
/* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null;
這個方法是取到了Thread類的一個例項變數ThreadLocalMap,而ThreadLocalMap是ThreadLocal的一個內部類
向下看,如果map是空,那麼已當前物件為k,當前物件就是ThreadLocal啊,引數為值存進map,就是說ThreadLocalMap的鍵是外部類ThreadLocal,值是我們存的Object。
簡單說,執行緒有一個例項屬性ThreadLocalMap,map鍵是外部類ThreadLocal,值是存放的Object。
第三步方法createMap
void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }
建立當前執行緒的ThreadLocalMap並存放值
其實到這裡,已經對ThreadLocal瞭解的差不多了,本身是鍵,而一個鍵只能對應一個值,所以肯定不會互相影響啦。
get/remove方法
remove方法
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
取出當前執行緒的ThreadLocalMap。如果存在,移除當前ThreadLocal為鍵的鍵值對
get方法
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
就簡單說了,取出當前執行緒的ThreadLocalMap,
如果map不為空取出當前ThreadLocal的Entry物件,取出entry物件的值返回
如果為空返回方法setInitialValue()
看方法
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
第一步方法initialValue()
protected T initialValue() {
return null;
}
返回一個null
下面的就和之前的差不多了就不贅述了,最後返回null。
這裡說一個我之前看到的ThreadLocal的‘坑’
如果我們專案使用的是執行緒池,我們知道執行緒池可能不會輕易關掉執行緒,也就是說對應的ThreadLocalMap一旦建立,如果不加處理,他的生命週期和Thread是一致的,那麼儲存的ThreadLocal物件的生命週期就不得而知了,久而久之,這個ThreadLocalMap越來越大,,會發生什麼,就不得而知了...
記錄到此