ThreadLocal

ThreadLocal是为了解决线程间数据共享带来的问题

  • 看下Thread, ThreadLocal和ThreadLocalMap之间的关系
ThreadLocal_第1张图片
image.png
  • 使用get方法的时候
public T get() {
        Thread t = Thread.currentThread(); //当前线程
        ThreadLocalMap map = getMap(t);  //获取线程中的数据结构ThreadLocalMap
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this); //ThreadLocal为key拿到ThreadLocalMap中的Entry
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value; //拿到Entry中存储的value
                return result;
            }
        }
        return setInitialValue();
    }

1.拿到当前Thread;
2.拿到当前线程中的数据结构ThreadLocalMap;
3.ThreadLocal作为key获取对应的Entry;
4.取到Entry中的value,就是存储的数据

ThreadLocal和ThreadLocalMap之间的关系

  • ThreadLocalMap.Entry继承了WeakReference, 它的key是一个ThreadLocal,所以ThreadLocal的生命周期结束之后,由于软应用,key也就是ThreadLocalMap也会在GC的时候被清除,达到回收内存的目的;这是建立在Thread会被销毁的情况下。

ThreadLocal存在的内存泄漏问题

  • 在线程池存在的情况下可能会出现内存溢出的情况,因为线程池中的线程coreSizePool线程在任务结束之后不会被销毁,而是回到空闲队列中。Thread的生命周期比ThreadLocal长很多,这样即使ThreadLocal的生命周期结束,Entry中的value依然是强引用,导致内存无法回收。

如何解决上述问题

  • try{}finally{} 关闭资源,threadLocal.remove()方法可以移除ThreadLocal对应的entry。

你可能感兴趣的:(ThreadLocal)