zoukankan      html  css  js  c++  java
  • 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);
    }
     
  • 相关阅读:
    CopyOnWriteArrayList源码阅读笔记
    ArrayList源码阅读笔记
    MySQL和Oracle的区别
    思维导图概览SpringCloud
    Java学习之Request篇
    Java学习之servlet篇
    Java学习之数据库连接池
    Java学习之注解篇
    Java爬取先知论坛文章
    Java学习之爬虫篇
  • 原文地址:https://www.cnblogs.com/sten/p/5777979.html
Copyright © 2011-2022 走看看