美文网首页
ThreadLocal学习

ThreadLocal学习

作者: 黄二的NPE | 来源:发表于2018-09-02 16:15 被阅读7次
    • ThreadLocal是什么和有什么用

    ThreadLocal这个类提供线程本地的变量。这些变量与一般正常的变量不同,它们在每个线程中都是独立的。ThreadLocal实例最典型的运用就是在类的私有静态变量中定义,并与线程关联。
    Synchronized用于线程间的数据共享,保证高并发的时候不会出现脏读问题;而ThreadLocal则用于线程间的数据隔离,每个线程都拥有一份独立的数据。所以ThreadLocal的应用场合,最适合的是按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。

    • Demo

    public class ThreadLocalTest {
        public static ThreadLocal<String> threadLocalMap = new ThreadLocal<>();
        public static void main(String[] args) throws Exception{
            threadLocalMap.set("main");
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    threadLocalMap.set("thread");
                }
            });
            t.start();
            //保证线程t执行完才sout
            t.join();
            //最后输出的是“main”
            System.out.println(threadLocalMap.get());
        }
    }
    

    按照以往的经验,我们是先set("main"),再set("thread"),那么应该输出的是后面set的"thread",这里却输出的是“main”。这是为什么呢?我们可以把threadLocal看做是以线程为key的map,但是这个map只能存放一个value。因为每个每个线程的key肯定不一样,所以取出value也不一样。即如果你在t的run方法里面get的话,那么输出的应该是"thread"。

    • 源码解析

    ThreadLocal --> set()
    public class ThreadLocal<T> {
        public void set(T value) {
            Thread t = Thread.currentThread();
            //map是当前线程的对象的一个成员变量threadLocals,可以把它看做是一个map,不过是以当threadLocal为key
            ThreadLocalMap map = getMap(t);
            if (map != null)
                map.set(this, value);
            else
                createMap(t, value);
        }
    
        ThreadLocalMap getMap(Thread t) {
            return t.threadLocals;
        }
    }
    
    class Thread implements Runnable {
      ThreadLocal.ThreadLocalMap threadLocals = null;
    }
    

    ThreadLocal --> get()

    public class ThreadLocal<T> {
        public T get() {
            Thread t = Thread.currentThread();
            //跟1.7之前的hashmap其实有点像
            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();
        }
    
        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;
        }
    }
    

    相关文章

      网友评论

          本文标题:ThreadLocal学习

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