ThreadLocal 工作原理。

看到ThreadLocal 有没有想起来 Thread 这个类?

那么就来说说ThreadLocal 是干嘛的吧!

作用:
ThreadLocal是一个线程内部的数据存储类。通过它可以在指定线程中存储数据,并获取到指定线程中的数据。

那么就跟着我一步步来解开疑惑吧~~

step1:
先实例化一个对象。

 private ThreadLocal<Boolean> mBooleanThreadLocal = new ThreadLocal<Boolean>();

step2: 开启两个线程

 mBooleanThreadLocal.set(true);
        Log.d(Tag, "getThread()-----------0" + Thread.currentThread() + "=" + mBooleanThreadLocal.get());


        new Thread(new Runnable() {
            @Override
            public void run() {
                mBooleanThreadLocal.set(false);
                Log.d(Tag, "getThread()---------1" + Thread.currentThread() + "=" + mBooleanThreadLocal.get());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d(Tag, "getThread()---------2" + Thread.currentThread() + "=" + mBooleanThreadLocal.get());
            }
        }).start();

大家可以猜想一下会出现什么样的值?
——-0 == true;
——-1 == false;
——-2 == true or false; 是不是还需要看那个线程先执行是吗?

这里写图片描述

答案是null 不知道看到这个答案是不是有点好奇为什么?

那我们来看下这个函数—- mBooleanThreadLocal.set(false);

/**
     * Sets the value of this variable for the current thread. If set to
     * {@code null}, the value will be set to null and the underlying entry will
     * still be present.
     *
     * @param value the new value of the variable for the caller thread.
     */
    public void set(T value) {
        Thread currentThread = Thread.currentThread();
        Values values = values(currentThread);
        if (values == null) {
            values = initializeValues(currentThread);
        }
        values.put(this, value);
    }

解释一下:

获取当前线程,在得到当前线程内部专门用于存储ThreadLocal的数据。
,然后再把这个value 值 存放到—-对应的这个线程 key.

在看一下怎么取出这个值的—— mBooleanThreadLocal.get()

/**
     * Returns the value of this variable for the current thread. If an entry
     * doesn't yet exist for this variable on this thread, this method will
     * create an entry, populating the value with the result of
     * {@link #initialValue()}.
     *
     * @return the current value of the variable for the calling thread.
     */
    @SuppressWarnings("unchecked")
    public T get() {
        // Optimized for the fast path.
        Thread currentThread = Thread.currentThread();
        Values values = values(currentThread);
        if (values != null) {
            Object[] table = values.table;
            int index = hash & values.mask;
            if (this.reference == table[index]) {
                return (T) table[index + 1];
            }
        } else {
            values = initializeValues(currentThread);
        }

        return (T) values.getAfterMiss(this);
    }

解释一下:
获取到这个线程对象,在获取到在这个线程保存的值,找到它在 set 时候 table[] 存放的位置信息。
1. 如果找到了 把存放的值返回回去。
2. 为什么会出现 线程——2 为 null的时候。
这是为什么啦?

可以看到 return (T) values.getAfterMiss(this);

然后就可以看到这个方法了

 protected T initialValue() {
        return null;
    }

参考:艺术探索第十章。

结束:
看到这些以上的解释,也就解开了我们开始疑惑了吧。

期待我下一篇的运行时注解吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值