美文网首页
ThreadLocal

ThreadLocal

作者: 追梦小蜗牛 | 来源:发表于2019-10-09 20:28 被阅读0次
    1.jpg

    简介:

    ThreadLocal是一个关于创建线程局部变量的类。通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离,锁机制:Synchronized是时间换取空间,ThreadLocal是空间换取时间。也就是说这里面存放的变量都只能被当前线程访问,其他线程干预不了。

    源码分析:

    /**
     * This class provides thread-local variables.  These variables differ from
     * their normal counterparts in that each thread that accesses one (via its
     * {@code get} or {@code set} method) has its own, independently initialized
     * copy of the variable.  {@code ThreadLocal} instances are typically private
     * static fields in classes that wish to associate state with a thread (e.g.,
     * a user ID or Transaction ID).
     **/
    

    ThreadLocal的内部有两个关键的静态内部类:ThreadLocalMap(哈希表)和Entry,Entry又是ThreadLocalMap的静态内部类。
    其中,ThreadLocalMap和线程绑定,Entry和ThreadLocal<K>对象绑定。

        public T get() {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null) {
                ThreadLocalMap.Entry e = map.getEntry(this);
                if (e != null) {
                    @SuppressWarnings("unchecked")
                    T result = (T)e.value;
                    return result;
                }
            }
            return setInitialValue();
        }
    

    get数据的流程:

    1. 首先获取到当前线程
    2. 根据当前线程获取绑定的ThreadLocalMap:return t.threadLocals;,threadLocals这个变量在Thread类里面定义。
    3. 判断map对象是否为null,是:构造一个ThreadLocalMap,把initialValue()这个方法的返回值设置到对应的ThreadLocalMap对象里面,并返回。否:直接从ThreadLocalMap里面取出Entry,然后再从过年Entry里面取出value属性的值。下图是构造函数的内容:
            ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
                table = new Entry[INITIAL_CAPACITY];
                int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
                table[i] = new Entry(firstKey, firstValue);
                size = 1;
                setThreshold(INITIAL_CAPACITY);
            }
    

    底层的数据结构是一个Entry数组,也就是哈希表。

        public void set(T value) {
            Thread t = Thread.currentThread();
            ThreadLocalMap map = getMap(t);
            if (map != null) {
                map.set(this, value);
            } else {
                createMap(t, value);
            }
        }
    

    set数据的流程:

    1. 首先获取到当前线程
    2. 根据线程获取ThreadLocalMap
    3. 判断map是否为null,是:构造ThreadLocalMap,在构造方法里面进行赋值,否:直接把值设置进去。

    场景:

    • 实现线程安全,非线程安全的对象使用ThreadLocal之后就会变得线程安全,因为每个线程都会有一个对应的实例。
    • 单个线程上下文信息存储。

    随便聊聊

    好久没有正式写技术博客了,以前断断续续的在其他地方都有写过,也都没有一直坚持写下去,形成系统。也不想给自己立下什么flag之类的,学习是内在驱动的,说再多也么用。随着时间的流逝,总结一些东西,写下心得体会,感觉越来越重要了,沉下心来继续学习。

    相关文章

      网友评论

          本文标题:ThreadLocal

          本文链接:https://www.haomeiwen.com/subject/thggpctx.html