ThreadLocal是用來存儲每一個線程的數據的法希,使用set和get來讀寫數據。
ThreadLocal<Object> local = new ThreadLocal<>();
local.set(6);
System.out.println(local.get());
ThreadLocal是用來維護ThreadLocalMap的忙厌。set和get操作都是對ThreadLocalMap操作。
每一個Thread都有一個單獨的ThreadLocalMap娶视。
ThreadLocalMap定義是在Thread里面隘蝎,使用是在threadlocal里面购啄。
ThreadLocalMap其實是一個默認大小16的數組,一個線程的每一個ThreadLocal占用一個位置末贾,這是通過ThreadLocalMap里面的threadLocalHashCode對數組長度取模實現的闸溃。
ThreadLocal內存溢出
存儲數據的Entry的key的ThreadLocal采用的弱引用,能被清理掉拱撵,但是value是強引用辉川,引用關系為:Thread -> ThreadLocalMap -> Entry -> Value,只要該線程不死拴测,那么這個強引用就一直存在乓旗,不會被清理掉,導致內存溢出集索。
解決方法為:
雖然ThreadLocal的作者想到了這點屿愚,也做了些優(yōu)化,例如在get的時候當發(fā)現key是null的時候务荆,會遍歷一次整個Entry數組妆距,remove掉key為null的entry,把value指向null函匕,消除這條強引用鏈娱据。源碼方法為expungeStaleEntry。
所以開發(fā)者要養(yǎng)成良好的習慣盅惜,記得用完ThreadLocal時中剩,調一次ThreadLocal.remove()方法或者ThreadLocal.set(null)