ThreadLocal的解析
2018-03-28 17:32
330 查看
ThreadLocal的使用
是线程私有的,那么必然是线程安全的,使用ThreadLocal实现线程本地存储的功能,也就是说我有个变量需要被一个线程独享,并且可以随时取用,那么ThreadLocal是一个很好的选择,比如在web开发中使用ThreadLocal存储User信息,方便随时调用,线程内部随时可以调用,相当于车子后面的后备箱。看看ThreadLocal的源码:
public void set(T value) { //取得当前线程对应的map Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); //如果map != null this为key if (map != null) map.set(this, value); else /**否则 void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } */ createMap(t, value); } public T get() { //首先取得当前线程 Thread t = Thread.currentThread(); //Thread类定义了一个map,ThreadLocal.ThreadLocalMap threadLocals = null; //thread上面挂了一个map,取得这个map ThreadLocalMap map = getMap(t); if (map != null) { //如果map != null ,取出this对应的entry ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; //取出存储数据 return result; } } return setInitialValue(); } ####ThreadLocal如何退出呢? 了解ThreadLocal的内部实现后,ThreadLocal是Thread类内部定义的,也就意味着ThreadLocal的生命周期和线程是相同的,线程不退出,那么ThreadLocal就无法被回收。 > - 线程退出的时候:
ThreadLocal如何退出呢?
了解ThreadLocal的内部实现后,ThreadLocal是Thread类内部定义的,也就意味着ThreadLocal的生命周期和线程是相同的,线程不退出,那么ThreadLocal就无法被回收。线程退出的时候:
private void exit() { if (group != null) { group.threadTerminated(this); group = null; } /* Aggressively null out all reference fields: see bug 4006245 */ target = null; /* Speed the release of some of these resources */ threadLocals = null; //这个地方为什么可以释放ThreadLocal资源,比较它存放在map里面,为什么可以像普通资源一样被释放?弱引用。 inheritableThreadLocals = null; inheritedAccessControlContext = null; blocker = null; uncaughtExceptionHandler = null; }
ThreadLocalMap使用了弱引用,也就是在map中存储的key不是直接持有引用,所以一旦外部直接引用被置为null,key会变成null,那么map中的value就会被GC回收。
static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
那么如果线程不关闭呢?比如线程池,如果线程一直没有exit,那么不同的对象调用,每个都会在ThreadLocalMap中维持一个entry,那么多来几次,可能会出现内存泄漏,那么如何处理?ThreadLocal.remove()方法可以实现这一点。
/** * Remove the entry for key. */ private void remove(ThreadLocal<?> key) { Entry[] tab = table; int len = tab.length; int i = key.threadLocalHashCode & (len-1); for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { if (e.get() == key) { e.clear(); expungeStaleEntry(i); return; } } }
相关文章推荐
- ThreadLocal原理解析(1):数据存取
- java ThreadLocal深入解析
- 解析ThreadLocal
- ThreadLocal原理解析
- ThreadLocal知识点解析
- ThreadLocal源码解析
- ThreadLocal---原理解析
- ThreadLocal深入解析
- ThreadLocal、ThreadLocalMap、Thread关系详细解析
- ThreadLocal源码解析
- ThreadLocal原理解析
- 【Java源码解析】ThreadLocal
- android ThreadLocal 深入解析
- ThreadLocal解析
- ThreadLocal原理解析
- 先码后看 JDK源码解析——ThreadLocal 侵立删
- JDK源码解析--- ThreadLocal
- 解析ThreadLocal
- ThreadLocal源码解析(一)
- ThreadLocal解析