我对ThreadLocal的理解

编程技术  /  houtizong 发布于 3年前   69
http://javarecipes.com/2012/07/11/understanding-the-concept-behind-threadlocal/
http://blog.csdn.net/qjyong/article/details/2158097

这两篇文章都认为ThreadLocal的实现原理说到底是一个Map<Thread currentThread, Object value>:
 public class CustomThreadLocal {     private static Map threadMap = new HashMap();     public static void add(Object object) {        threadMap.put(Thread.currentThread(), object);    }     public static void remove(Object object) {        threadMap.remove(Thread.currentThread());    }     public static Object get() {        return threadMap.get(Thread.currentThread());    } }


我认为, 这个观点只有一半是正确的。
ThreadLocal确实是通过Map来实现,但这个Map的key并不是Thread.curentThread,而是ThreadLocal的实例本身。

简单地说,ThreadLocal的关键的地方在下面两点:
1.同一线程内,把某值(假设为someValue)存储在ThreadLocal内,那么可以在本线程内的任意其他地方、任意其他时间获得这个值
2.对于其他线程来说,第1点里面的someValue是不可见的

这是怎么做到的呢?
这是通过“每一个线程,都持有一个ThreadLocal.ThreadLocalMap的实例”来实现的。

查看Thread源码,Thread有一个实例域:
ThreadLocal.ThreadLocalMap threadLocals = null;
而ThreadLocal.ThreadLocalMap就是一个Map。

查看ThreadLocal.ThreadLocalMap,发现它的key就是当前的ThreadLocal:
ThreadLocal.ThreadLocalMap的set方法:
private void set(ThreadLocal key, Object value) {/*......*/}


再返回去看看ThreadLocal的set方法:
     public void set(T value) {        Thread t = Thread.currentThread();        ThreadLocalMap map = getMap(t);        if (map != null)            map.set(this, value);        else            createMap(t, value);    }


可以清晰地看到,ThreadLocal.ThreadLocalMap的key就是this,也就是当前的ThreadLocal


举例:
class MyThreadLocalA {    private static final ThreadLocal threadLocalInstanceA = new ThreadLocal();        public static Object get() {        return threadLocalInstanceA.get();    }    /*.....*/}class MyThreadLocalB {    private static final ThreadLocal threadLocalInstanceB = new ThreadLocal();    public static Object get() {        return threadLocalInstanceB.get();    }    /*.....*/}


假设有两个线程,分别是threadX和threadY
假设threadX访问MyThreadLocalA时,放入值"X_A",访问MyThreadLocalB时放入值"X_B"
假设threadY访问MyThreadLocalA时,放入值"Y_A",访问MyThreadLocalB时放入值"Y_B"

那么
threadX.threadLocals(我们称之为xMap)会是这样:
key value---------------------------------------------threadLocalInstanceAX_AthreadLocalInstanceBX_B


threadY.threadLocals(我们称之为yMap)会是这样:
key value---------------------------------------------threadLocalInstanceAY_AthreadLocalInstanceBY_B


那么在线程threadX内执行MyThreadLocalA.get(),得到的值就会是"X_A"。
具体流程:
MyThreadLocalA.get()-->threadLocalInstanceA.get() -->Thread.currentThread.threadLocals(也就是xMap)  -->xMap.getEntry(this)(这里的this就是threadLocalInstanceA)   -->得到"X_A"


其实过程很清晰。别人说的再多,还不如自己去看看源代码~   

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客