ThreadLocal原理用法詳解ThreadLocal記憶體洩漏
ThreadLocal
https://github.com/CyC2018/CS-Notes/blob/master/notes/Java%20%E5%B9%B6%E5%8F%91.md#2-%E7%BA%BF%E7%A8%8B%E6%9C%AC%E5%9C%B0%E5%AD%98%E5%82%A8thread-local-storage
ThreadLocal,即執行緒變數
常用的3個方法:set()、get()、remove()。都是執行緒安全的。
一個ThreadLocal在一個執行緒中是共享的,在不同執行緒之間又是隔離的(每個執行緒都只能看到自己執行緒的值)
public class ThreadLocalExample1 {
public static void main(String[] args) {
ThreadLocal threadLocal1 = new ThreadLocal();
ThreadLocal threadLocal2 = new ThreadLocal();
Thread thread1 = new Thread(() -> {
threadLocal1.set(1);
//threadLocal1.set(11);會覆蓋上面的set(1)
threadLocal2.set(1);
});
Thread thread2 = new Thread(() -> {
threadLocal1.set(2);
threadLocal2.set(2);
});
thread1.start();
thread2.start();
}
}
ThreadLocal原理
每個 Thread 都有一個 ThreadLocal.ThreadLocalMap 物件。
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
set
ThreadLocal.ThreadLocalMap threadLocals = null;
...
public void set(T value) {
Thread t = Thread.currentThread();
//獲取當前執行緒的ThreadLocalMap;
ThreadLocalMap map = getMap(t);
if (map != null)
//this是呼叫set()方法的localthread物件;
map.set(this, value);
else
createMap(t, value);
}
...
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
set()先獲取當前執行緒的ThreadLocalMap,然後將呼叫set()方法的localthread物件作為key儲存value,
這樣的話,ThreadLocal threadLocal1 = new ThreadLocal(),執行緒a呼叫threadLocal1.set方法時,執行緒a會建立ThreadLocalMap物件,key是threadLocal1;
當執行緒呼叫threadLocal1.get時,執行緒a便會到自己的ThreadLocalMap中,根據key==threadLocal1獲取value,這樣便是執行緒安全的,每個執行緒都有自己的ThreadLocalMap
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();
}
get方法,先獲取當前執行緒的ThreadLocalMap,然後根據將呼叫get()方法的localthread物件作為key獲取value;
ThreadLocal記憶體洩漏
記憶體洩露:程式在申請記憶體後,無法釋放已申請的記憶體空間,一次記憶體洩露危害可以忽略,但記憶體洩露堆積後果很嚴重;
ThreadLocalMap的key
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;
}
}
...
}
如上圖,每一個Thread維護一個ThreadLocalMap,key弱引用,外部的ThreadLocalRef是key的強引用,一旦ThreadLocalRefnull,GC時key就會被回收,但是value還存在強引用,只有CurrentThreadRefnull,value才會被回收;
這些key為null的Entry的value就會一直存在一條強引用鏈
CurrentThreadRef -> CurrentThread -> ThreaLocalMap -> Entry -> value
public class ThreadLocalExample1 {
public static void main(String[] args) {
ThreadLocal threadLocal1 = new ThreadLocal();
Thread thread1 = new Thread(() -> {
while(true){
threadLocal1.set(1);
}
});
threadLocal1 = null;
System.GC();//如果在這裡發生GC,那麼threadLocal1以及thread1的ThreaLocalMap的key會被回收,但是value不會被回收;
thread1.start();
}
}
https://blog.csdn.net/puppylpg/article/details/80433271
https://zhuanlan.zhihu.com/p/102571059
相關文章
- ThreadLocal記憶體洩漏問題thread記憶體
- ThreadLocal真會記憶體洩漏?thread記憶體
- ThreadLocal記憶體洩漏怎麼回事thread記憶體
- 分析ThreadLocal的弱引用與記憶體洩漏問題thread記憶體
- 一篇文章,從原始碼深入詳解ThreadLocal記憶體洩漏問題原始碼thread記憶體
- ThreadLocal會不會有所謂“記憶體洩漏”的問題thread記憶體
- 證明:ThreadLocal的get,set方法無法防止記憶體洩漏thread記憶體
- ThreadLocal原始碼解讀和記憶體洩露分析thread原始碼記憶體洩露
- 阿里二面:談談ThreadLocal的記憶體洩漏問題?問麻了。。。。阿里thread記憶體
- ThreadLocal用法及原理thread
- JUC---ThreadLocal原理詳解thread
- Java 中 ThreadLocal 記憶體洩露的例項分析Javathread記憶體洩露
- 記憶體洩漏記憶體
- ThreadLocal原始碼解析,記憶體洩露以及傳遞性thread原始碼記憶體洩露
- 分析記憶體洩漏和goroutine洩漏記憶體Go
- Java面試題:細數ThreadLocal大坑,記憶體洩露本可避免Java面試題thread記憶體洩露
- js記憶體洩漏JS記憶體
- Java記憶體洩漏Java記憶體
- webView 記憶體洩漏WebView記憶體
- Javascript記憶體洩漏JavaScript記憶體
- Java記憶體洩漏解決之道Java記憶體
- 深入瞭解 JavaScript 記憶體洩漏JavaScript記憶體
- Threadlocal詳解(ThreadLocal,InheritTableThreadLocal,TransmittableThreadLocal)threadMIT
- Netty原始碼學習8——從ThreadLocal到FastThreadLocal(如何讓FastThreadLocal記憶體洩漏doge)Netty原始碼threadAST記憶體
- Java中ThreadLocal的用法和原理Javathread
- 面試:為了進阿里,死磕了ThreadLocal記憶體洩露原因面試阿里thread記憶體洩露
- 記憶體分析與記憶體洩漏定位記憶體
- 記憶體洩漏和記憶體溢位記憶體溢位
- Handler記憶體洩漏分析及解決記憶體
- valgrind 記憶體洩漏分析記憶體
- Android 記憶體洩漏Android記憶體
- Android記憶體洩漏Android記憶體
- 淺談記憶體洩漏記憶體
- 記憶體洩漏的原因記憶體
- JavaScript 記憶體洩漏教程JavaScript記憶體
- 說說 記憶體洩漏記憶體
- 007 LeakCanary 記憶體洩漏原理完全解析記憶體
- 【記憶體洩漏和記憶體溢位】JavaScript之深入淺出理解記憶體洩漏和記憶體溢位記憶體溢位JavaScript