美文网首页
ThreadLocal 理解

ThreadLocal 理解

作者: _水杉 | 来源:发表于2019-12-02 23:57 被阅读0次

Thread 变量 threadLocals

线程类Thread内部有一个名为threadLocalsThreadLocal.ThreadLocalMap 变量,它定义如下:

/* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

ThreadLocal.ThreadLocalMap

ThreadLocal.ThreadLocalMapThreadLocal 的内部类

    /**
     * ThreadLocalMap is a customized hash map suitable only for
     * maintaining thread local values. No operations are exported
     * outside of the ThreadLocal class. The class is package private to
     * allow declaration of fields in class Thread.  To help deal with
     * very large and long-lived usages, the hash table entries use
     * WeakReferences for keys. However, since reference queues are not
     * used, stale entries are guaranteed to be removed only when
     * the table starts running out of space.
     */
    static class ThreadLocalMap {
        // ...
    }

看注释的第一句话 ThreadLocalMap is a customized hash map suitable only for maintaining thread local values. 意思是 ThreadLocalMap 是一个自定义 HashMap,只适用于线程局部变量。完全可以把它看做是一个 HashMap。

也就是说,在 Thread 内部有一个类似 HashMap 的成员变量

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).
 *
 * <p>For example, the class below generates unique identifiers local to each
 * thread.
 * A thread's id is assigned the first time it invokes {@code ThreadId.get()}
 * and remains unchanged on subsequent calls.
 * 
 * ...
 *
 * @author  Josh Bloch and Doug Lea
 * @since   1.2
 */
public class ThreadLocal<T> {
    //...
}

大致意思就是,ThreadLocal 提供线程局部的变量,这些变量在每个线程中都有不同的副本,通过get和set方法就可以得到或设置它们。

ThreadLocal的结构如下:

类`ThreadLocal`的结构

重要的方法只有两个:set 和 get

ThreadLocal.set(value)

ThreadLocal.set(value)Thread 内部的 threadLocals 变量添加值,它的实现如下:

    // line 189
    /**
     * Sets the current thread's copy of this thread-local variable
     * to the specified value.  Most subclasses will have no need to
     * override this method, relying solely on the {@link #initialValue}
     * method to set the values of thread-locals.
     *
     * @param value the value to be stored in the current thread's copy of
     *        this thread-local.
     */
    public void set(T value) {
       // 获取当前线程
        Thread t = Thread.currentThread();
        // 获取线程内部 ThreadLocalMap 对象
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else// 给线程threadLocals变量new一个ThreadLocalMap对象,并添加第一个键值对
            createMap(t, value);
    }
    ......
    // line 225
    /**
     * Get the map associated with a ThreadLocal. Overridden in
     * InheritableThreadLocal.
     *
     * @param  t the current thread
     * @return the map
     */
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

    /**
     * Create the map associated with a ThreadLocal. Overridden in
     * InheritableThreadLocal.
     *
     * @param t the current thread
     * @param firstValue value for the initial entry of the map
     */
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

ThreadLocal.get()

    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();
    }

小结

ThreadLocalSynchronized都是为了解决多线程中相同变量的访问冲突问题,不同的是:

  • Synchronized 是通过线程等待,牺牲时间来解决访问冲突
  • ThreadLocal 是通过每个线程单独一份存储空间,牺牲空间来解决冲突,并且相比于SynchronizedThreadLocal 具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问到想要的值。

正因为ThreadLocal的线程隔离特性,使他的应用场景相对来说更为特殊一些。在android中Looper、ActivityThread以及AMS中都用到了ThreadLocal。当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候,就可以考虑采用ThreadLocal。

相关文章

  • ThreadLocal

    理解ThreadLocal 理解ThreadLocal的关键在于理解 Thread, threadLocals, ...

  • ThreadLocal的使用事例

    列举几个使用ThreadLocal的事例,能更好的理解ThreadLocal。 1、运用ThreadLocal实现...

  • 14-ThreadLocal类详细剖析

    ThreadLocal类详细剖析 对ThreadLocal的理解 JDK中的源码是这样描述ThreadLocal的...

  • ThreadLocal 深度解析

    一.对ThreadLocal的理解二.深入解析ThreadLocal类三.ThreadLocal的应用场景 对Th...

  • ThreadLocal源码分析

    1.对ThreadLocal的理解 ThreadLocal是一个创建线程局部量的类。使用ThreadLocal创建...

  • ThreadLocal理解

    一、ThreadLocal的作用 ThreadLocal以线程作为作用域,针对每个线程维护他们自己的数据。每个线程...

  • ThreadLocal理解

    a

  • ThreadLocal理解

    MARK网址http://m.blog.csdn.net/article/details?id=24314381 ...

  • 理解ThreadLocal

    概述 ThreadLocal是一种线程封闭技术,用于隔离线程间的数据,从而避免使用同步控制。 一种避免使用同步的方...

  • ThreadLocal 理解

    Thread 变量 threadLocals 线程类Thread内部有一个名为threadLocals 的 Thr...

网友评论

      本文标题:ThreadLocal 理解

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