ThreadLocal
ThreadLocal
作用:
- 提供线程内局部变量,多线程场景下不同线程之间不会相互干扰。
- ThreadLocal 实例通常来说都是 private static 修饰的,用于关联线程、线程上下文。
- 减少同一个线程内的函数 或 组件之间传递变量的复杂性。
基本方法:

demo:
ThreadLocal处理多线程问题,将变量与线程绑定:
public class ThreadLocalDemo {
    private String Msg;
    ThreadLocal<String> threadLocal = new ThreadLocal<>();
    private String getMsg(){
        return threadLocal.get();
    }
    private void setMsg(String s){
        threadLocal.set(s);
    }
    public static void main(String[] args) {
        ThreadLocalDemo threadLocalDemo = new ThreadLocalDemo();
        for(int i =0;i<10;i++){
            Thread thread = new  Thread(new Runnable() {
                @Override
                public void run() {
                    threadLocalDemo.setMsg(Thread.currentThread().getName()+"的数据");
                    System.out.println("--------------------------------------");
                    System.out.println(Thread.currentThread().getName()+", 保存的数据------>" + threadLocalDemo.getMsg());
                }
            });
            thread.start();
        }
    }
}
运行结果:
Thread-0, 保存的数据------>Thread-0的数据
--------------------------------------
Thread-1, 保存的数据------>Thread-1的数据
--------------------------------------
Thread-2, 保存的数据------>Thread-2的数据
--------------------------------------
Thread-3, 保存的数据------>Thread-3的数据
--------------------------------------
Thread-4, 保存的数据------>Thread-4的数据
--------------------------------------
Thread-5, 保存的数据------>Thread-5的数据
--------------------------------------
Thread-6, 保存的数据------>Thread-6的数据
--------------------------------------
Thread-7, 保存的数据------>Thread-7的数据
--------------------------------------
Thread-9, 保存的数据------>Thread-9的数据
--------------------------------------
Thread-8, 保存的数据------>Thread-8的数据
验证可知,每个线程拿到的都是自己的数据。
ThreadLocal数据结构:
ThreadLocal的设计是:每个Thread维护一个ThreadLocalMap哈希表,这个哈希表的key是ThreadLocal实例本身,value才是真正要存储的值Object。
 (1) 每个Thread线程内部都有一个Map (ThreadLocalMap)
 (2) Map里面存储ThreadLocal对象(key)和线程的变量副本(value)
 (3) Thread内部的Map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。
 (4) 对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干扰。
ThreadLocal可能引起的问题:
内存泄漏
问题背景:

- 源码可知,在ThreadLocalMap中,用Entry来保存K-V结构数据的。但是Entry中key是ThreadLocal对象。
- 源码可知,Entry继承WeakReference,使用弱引用,可以将ThreadLocal对象的生命周期和线程生命周期解绑。
- 强引用( “Strong” Reference) , 最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾回收器就不会回收这种对象。
- 弱引用( WeakReference) ,垃圾回收器发现只具有弱引用的对象,无论当前内存空间足够与否,都会回收。
问题原因:在当前线程依旧运行情况下,业务代码中使用完线程的ThreadLocal对象后被回收,则TheadLocalMap中Entry的key为null,此时Entry中value依然存在,且key为null,则value无法被访问到,内存泄漏。
处理方式:使用完ThreadLocal ,手动调用其remove方法删除对应的Entry。

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号