目录
- 一、使用方式:
- 二、ThreadLocalMap
一、使用方式:
publicclassThreadLocalManager{privatefinalMap<String,String>map=newHashMap<>();privatestaticfinalThreadLocal<ThreadLocalManager>THREAD_LOCAL=ThreadLocal.withInitial(ThreadLocalManager::new);publicstaticvoidput(Stringkey,Stringvalue){THREAD_LOCAL.get().map.put(key,value);}publicstaticStringget(Stringkey){returnTHREAD_LOCAL.get().map.get(key);}publicstaticvoidremoveCurrentThread(){THREAD_LOCAL.remove();}publicstaticvoidmain(String[]args){try{ThreadLocalManager.put("key","value");System.out.println(get("key"));}finally{ThreadLocalManager.removeCurrentThread();}}}二、ThreadLocalMap
每个Thread维护一个ThreadLocalMap实例变量,因此每个线程只能操作自己的ThreadLocalMap。使用ThreadLocal只不过是在每个线程的ThreadLocalMap中添加了一个弱引用指向ThreadLocal对象为key的Entry,ThreadLocal本身只是一个访问线程内部ThreadLocalMap实例变量的工具,依靠在线程内部的实例变量上存取数据来保证隔离性。对应上面的代码就是ThreadLocal在线程的ThreadLocalMap实例变量中创建了一个Entry<ThreadLocal,new ThreadLocalManager()>,通过ThreadLocal存取数据本质上是访问线程实例变量ThreadLocalMap中的Entry。
内存泄漏问题:当ThreadLocal对象没有强引用时,那么此时只有Entry的key这个弱引用指向ThreadLocal对象,当GC时ThreadLocal对象就会被回收,此时key指向null,但是value被ThreadLocalMap强引用,所以Entry既不能取出也不会被回收,除非线程结束运行ThreadLocalMap被会收。内存泄漏主要发生在线程池中的线程使用ThreadLocal时,正常结束的请求线程没必要清理,因为ThreadLocalMap会被直接清理。
防止内存泄漏的最好方法就是线程使用完存入ThreadLocal中的数据后及时调用remove()方法清除当前线程中ThreadLocalMap里对应的Entry。