ThreadLocal-分析-总结以及使用场合

首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。

Thread与ThreadLocal有什么关系?

其实真正的奥秘就在Thread类中的一行:

ThreadLocal.ThreadLocalMap threadLocals = null;

 其中ThreadLocalMap的定义是在ThreadLocal类中,真正的引用却是在Thread类中

接下来的重点是ThreadLocalMap中用于存储数据的entry

static class Entry extends WeakReference<ThreadLocal> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }

 从中我们可以发现这个Map的key是ThreadLocal变量,value为用户的值

至此,我们了解:

1.Thread类中有一个成员变量叫做ThreadLocalMap,它是一个Map,他的Key是ThreadLocal类

2.每个线程拥有自己的申明为ThreadLocal类型的变量,所以这个类的名字叫'ThreadLocal':线程自己的(变量)

3.此变量生命周期是由该线程决定的,开始于第一次初始(get或者set方法)

4.由ThreadLocal的工作原理决定了:每个线程独自拥有一个变量,并非共享或者拷贝

 接下来分析一下源码:

关键方法代码

/**
 * 关键方法,返回当前Thread的ThreadLocalMap
 * [[[每个Thread返回各自的ThreadLocalMap,所以各个线程中的ThreadLocal均为独立的]]]
 */
ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

Threadlocal的get方法代码

public T get() {
        Thread t = Thread.currentThread();
        /**
         * 得到当前线程的ThreadLocalMap
         */
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            /**
             * 在此线程的ThreadLocalMap中查找key为当前ThreadLocal对象的entry
             */
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

初始化方法代码

private T setInitialValue() {
        /**
         * 默认返回null,这个方法为protected可以继承
         */
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            /**
             * 初次创建
             */
            createMap(t, value);
        return value;
    }
    /** 
     * 给当前thread初始ThreadlocalMap 
     */  
    void createMap(Thread t, T firstValue) {  
            t.threadLocals = new ThreadLocalMap(this, firstValue);  
        }  

即:每个线程都拥有一个自己的ThreadLocalMap对象,而这个对象的key是ThreadLocal类型的,这个key在每个线程中都是一样的,ThreadLocal只是作为一个索引。

http://www.iteye.com/topic/777716

http://www.iteye.com/topic/103804

http://blog.csdn.net/indexchen/article/details/1685226

http://www.cnblogs.com/dolphin0520/p/3920407.html

 Spring 如何处理并发:

http://blog.csdn.net/lin910429/article/details/38404761/

猜你喜欢

转载自z724130632.iteye.com/blog/2301095