Java并发编程读书笔记——ThreadLocal

1. ThreadLocal定义:线程变量,是一个以ThreadLocal对象为键,任意对象为值得存储结构。

2. 作用:提供线程内得局部变量,在线程的生命周期内起作用,在本线程内随时可取,隔离其它的线程。

下面写了一个简单的例子:

/**
 * 是一个以ThreadLocal对象为键,任意对象为值得存储结构;
 * 一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上得一个值
 */
public class Profiler {

    private static ThreadLocal<Long> TIME_THREADLOCAL = new ThreadLocal<Long>(){
        //设定初始值
        @Override
        protected Long initialValue() {
            return System.currentTimeMillis();
        }
    };

    //为ThreadLocal设置指定的值
    public static final void begin(){
        TIME_THREADLOCAL.set(System.currentTimeMillis());   //set()  设置ThreadLocal中的值
    }

    public  static final Long end(){
        return System.currentTimeMillis() - TIME_THREADLOCAL.get(); //get()获取ThreadLocal中的值
    }

    public static void main(String[] args) throws InterruptedException {
        Profiler.begin();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("Cost: "+Profiler.end()+" mills");
    }
}

这段代码,首先设置一个当前系统时间为初始值,使线程睡眠一秒,调用end()方法,查看begin()和end()方法所运行的时间,输出结果为:


通过上面,对ThreadLocal有了一定的了解。

3. ThreadLocal中方法:

        get():获取ThreadLocal上绑定的值;

        set():为ThreadLocal设定值;

        remove():将当前线程的ThreadLocal绑定的值删除。

4. ThreadLocal的实现:(JDK1.8ThreadLocal源码)

        下面看一下get()方法的源码:

/**
     * Returns the value in the current thread's copy of this
     * thread-local variable.  If the variable has no value for the
     * current thread, it is first initialized to the value returned
     * by an invocation of the {@link #initialValue} method.
     *
     * @return the current thread's value of this thread-local
     */
    public T get() {
        Thread t = Thread.currentThread();    //获取当前线程
        ThreadLocalMap map = getMap(t);        //根据当前线程获取一个map,看后面getMap()源码
        if (map != null) {        
            ThreadLocalMap.Entry e = map.getEntry(this);    //如果map不为空
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;        //返回map中的value
            }
        }
        return setInitialValue();    //如果map为空,设置初始值
    }
    getMap()的源码:
/**
     * 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;    //返回一个ThreadLocalMap对象
    }

setInitialValue函数的源码:

/**
     * Variant of set() to establish initialValue. Used instead
     * of set() in case user has overridden the set() method.
     *
     * @return the initial value
     */
    private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }

createMap函数的源码:

/**
     * 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);
    }

通过上面对get()方法的源码的简单分析,总结出:

        每个Thread维护一个ThreadLocalMap映射表,这个映射表的key是ThreadLocal实例本身,value是真正需要存储的Object。

猜你喜欢

转载自blog.csdn.net/crazer_cy/article/details/79685651