我对ThreadLocal的理解

[url]http://javarecipes.com/2012/07/11/understanding-the-concept-behind-threadlocal/[/url]
[url]http://blog.csdn.net/qjyong/article/details/2158097[/url]

这两篇文章都认为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
---------------------------------------------
threadLocalInstanceA X_A
threadLocalInstanceB X_B


threadY.threadLocals(我们称之为yMap)会是这样:
key 													value
---------------------------------------------
threadLocalInstanceA Y_A
threadLocalInstanceB Y_B


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


其实过程很清晰。别人说的再多,还不如自己去看看源代码~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值