大部分翻譯自How is ThreadLocal implemented?對(duì)代碼作了更新
這是一個(gè)關(guān)于跳脫固有框架思考的例子,建議你花5分鐘閱讀全文,一定有所收獲
ThreadLocal介紹
Implements a thread-local storage, that is, a variable for which each thread has its own value. All threads share the same {@code ThreadLocal} object ,but each sees a different value when accessing it, and changes made by one thread do not affect the other threads. The implementation supports {@code null} values.
大概意思是說,一個(gè)ThreadLocal變量可以為不同的線程保存不同的值
實(shí)現(xiàn)
通過介紹可知,可以為線程保存本地變量,那么我們可能需要一個(gè)Map對(duì)象,即ThreadLocal<T>變量內(nèi)部維護(hù)一個(gè)HashMap<Thread,T>對(duì)象,其中,KEY可以通過Thread.currentThread()來獲取,但是HashMap不是線程安全的,我們可以用Hashtable(相當(dāng)于為每個(gè)方法加了同步原語synchronize的HashMap,效率低)或者ConcurrentHashMap(鎖分段技術(shù),效率高點(diǎn))代替,一旦你使用這樣的方式實(shí)現(xiàn),那么需要面對(duì)的問題有兩:
- 1、內(nèi)存泄漏風(fēng)險(xiǎn),因?yàn)镵EY為
Thread - 2、同步的開銷
為了解決第一個(gè)問題可以考慮使用弱應(yīng)用替代Thread的強(qiáng)引用,但關(guān)于同步的開銷明顯是沒有更好的方法解決了?
但實(shí)際上JDK中的實(shí)現(xiàn)并不是這樣的且更加優(yōu)雅,前面我們考慮以Thread作為KEY記錄在ThreadLocal來為Thread保存線程獨(dú)有的變量,而JDK的實(shí)現(xiàn)則是剛好與我們相反,用Thread來記錄這樣的一個(gè)以ThreadLocal-Object的映射關(guān)系(不一定是用JAVA中的Map容器來實(shí)現(xiàn))
以Android23的為例子
public class Thread implements Runnable {
ThreadLocal.Values localValues;
// cut for brevity
}
public class ThreadLocal<T> {
// cut for brevity
static class Value {
private Object[] table;
void put(ThreadLocal<?> keys, Object value) {
cleanUp();
int firstTombstone = -1;
for (int index = key.hash & mask;; index = next(index)) {
Object k = table[index];
if (k == key.reference) {
// Replace existing entry.
table[index + 1] = value;
return;
}
}
}//end put
//........
}//end Value
public void set(T value) {
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values == null) {
values = initializeValues(currentThread);
}
values.put(this, value);
}
Values initializeValues(Thread current) {
return current.localValues = new Values();
}
// ...
}//end ThreadLocal
Thread記錄了一個(gè)ThreadLocal.Value實(shí)例,用來記錄了[ThreadLocal實(shí)例-線程本地變量]的映射,Key為hash值,不用擔(dān)心內(nèi)存泄漏問題,并且避免了同步所帶來的開銷問題,的確是十分優(yōu)雅的實(shí)現(xiàn)