关于ThreadLocal,网络上的文章不计其数,一开始我也是无从下手,费了好大劲才搞懂,现在把自己理解的ThreadLocal记录在博客,以帮助到更多同学;

我理解的ThreadLocal

ThreadLocal中文名叫线程变量,它底层维护了一个map,key就是当前的ThreadLocal对象(可以理解为当前执行该段代码的线程),value就是你set的值,这个map保证了各个线程的数据互不干扰

	//这是ThreadLocal类的set方法源码
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
        	//看这行,精华就在这行
            map.set(this, value);
        else
            createMap(t, value);
    }
	//这是get方法
    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
        	//精华在这儿,用人话讲就是通过当前线程对象去map里面找对应的entry
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
            	//entry.value就拿到你set的value啦
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

ThreadLocal和Synchonized对比

Synchonized不用多说,不清楚的请移步synchronized底层实现原理

而ThreadLocal为解决并发编程提供了新的思路,synchronized是共享线程间的数据,而ThreadLocal是隔离线程间的数据

synchronized是利用锁的机制,使变量或代码块在某一时该只能被桶一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。

ThreadLocal使用不当引起的内存泄漏

ThreadLocal大法虽然好,但是使用不当后果很严重

造成原因:

ThreadLocal没有外部强引用,在发生垃圾回收的时候,ThreadLocal会被当成垃圾给干掉,而ThreadLocal对象又是Map中的key,map的key没了,那对应的entry永远不会被访问到,就无法被回收,进而造成内存泄漏

解决方案:

1、每次用完ThreadLocal都调用它的remove()方法清除数据
2、将ThreadLocal变量定义成private static,这样就一直存在ThreadLocal的强引用,也就能保证任何时候都能通过ThreadLocal的弱引用访问到Entry的value值,进而被清除


ok我话讲完