ThreadLocal

1、什么是ThreadLocal

ThreadLocal用于设置当前线程的特有变量,即它里面设置的变量仅在当前线程中有效

在单线程环境下,ThreadLocal中设置的变量可以看成是一个普通变量,而在多线程环境下,即使线程A和线程B操作同一个ThreadLocal,他们获取的值也不一定相同(线程A往threadLocal中添加的变量线程B获取不到)

2、常用方法

threadLocal.set(Object object):向ThreadLocal实例中添加一个变量

threadLocal.get():获取当前ThreadLocal实例中的变量

单线程环境下执行ThreadLocal的set和get方法:

         ThreadLocal<Object> local = new ThreadLocal<>();
         local.set("张三");                      //往ThreadLocal实例中存值
         System.out.println(local.get());       //获取当前ThreadLocal中的值

 运行结果:控制台中打印   "张三"

多线程环境下执行ThreadLocal的set和get方法

        //获取threadlocal本地线程对象
        ThreadLocal<Object> threadLocal = new ThreadLocal<>();
        //往本地线程中设置变量
        threadLocal.set(new Object());
        new Thread() {               //匿名内部类方式创建一个新的线程对象
            public void run() {
                System.out.println(threadLocal.get());
            }
        }.start();    //启动线程
        Thread.sleep(1000);             //确保子线程先执行
        System.out.println(threadLocal.get());

运行结果:控制台打印null(这是子线程中打印的),紧接着打印一个Object对象(这是主线程即main方法所在的线程打印的)。

由此可知,对于同一个threadLocal对象,主线程中设置的变量,子线程是获取不到的。

3、原因(关于ThreadLocal的get方法和set方法源码解析)

set方法:

源码

    public void set(T value) {
        Thread t = Thread.currentThread();     //获取当前线程
        ThreadLocalMap map = getMap(t);        //通过当前线程去获取一个map集合
        if (map != null)                       //如果map!=null,则直接往map中添值
            map.set(this, value);
        else
            createMap(t, value);               //如果map==null,则创建一个当前线程的map集合
    }


    //getMap方法
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

    //createMap方法
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

ThreadLocal实例的set方法本质上其实就是往一个map集合中添加数据,

map集合中的key是当前ThreadLocal的实例对象,value是该实例对象中存储的变量。

get方法:

源码:

   public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);             //获取当前线程的map集合
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);    //获取map中的一项元素
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;             //获取entry中的value
                return result;
            }
        }
        return setInitialValue();
    }

get方法就是获取当前线程的map集合,然后从map集合中去获取当前threadLocal对象对应的entry,根据entry去获取value

总结:

ThreadLocal的set和get方法实际上都是通过去获取线程对象(Thread对象)中维护的一个map集合进行操作的,由于不同线程对象中的map集合不相同,所以ThreadLocal设置的变量仅在当前线程中可见,在其他线程中的获取不到的

而在单线程环境下,ThreadLocal对象的获取的map集合是同一个,所以可以看成是一个普通变量

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值