ThreadLocal说明

 
    通常,程序中的对象在多线程下,数据都是竞争共享的。但是,有一个类例外,他生成的实例是线程私有的,ThreadLocal。ThreadLocal生成的对象,线程私有,这是怎么做到的呢?
 
先看个实例:
public class Test {
 
    private ThreadLocal<String> stringThreadLocal = new ThreadLocal<>() ;
    private ThreadLocal<String> stringThreadLocal2 = new ThreadLocal<>() ;
 
    public void print() {
        System.out.println("threadName:" + Thread.currentThread().getName() + ",value:" + stringThreadLocal.get());
        System.out.println("threadName:" + Thread.currentThread().getName() + ",value:" + stringThreadLocal2.get());
    }
 
    public void setValue(String value) {
        stringThreadLocal.set(value);
        stringThreadLocal2.set(value + "——2");
    }
 
    public static void main(String[] args) throws InterruptedException {
 
        Test test = new Test() ;
        test.setValue("test0");
        test.print();
 
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                test.setValue("test1");
                test.print();
            }
        }) ;
        thread1.start();
 
        Thread.sleep(1000);
 
        test.print();
    }
}

 

 
输出:
threadName:main,value:test0
threadName:main,value:test0——2
threadName:Thread-0,value:test1
threadName:Thread-0,value:test1——2
threadName:main,value:test0
threadName:main,value:test0——2

 

 
从输出结果,看出stringThreadLocal和stringThreadLocal2结果不同,大家可能好理解;但是线程main,和线程 Thread-0 从属性stringThreadLocal和stringThreadLocal2获取的值是不同的,就不是很好理解了。
 
其实Thread类有一个map,存放相同线程不同ThreadLocal对象对应的值(key为ThreadLocal,value为需要存储的值);ThreadLocal就是对线程Thread内部这个map的管理,不同的线程获取的map不同,不同的ThreadLocal获取的value也不同。
 
如下ThreadLocal源码:
public T get() {
    //  获取当前线程
    Thread t = Thread.currentThread();
    // 获取当前Thread的map
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        // 获取当前ThreadLocal对象对应的entry
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}
// 获取当前线程对应的map
ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}
 
public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null)
        map.set(this, value);
    else
        createMap(t, value);
}

 

 
posted @ 2016-08-16 21:40  li.zhiliang  阅读(201)  评论(0编辑  收藏  举报