ThreadLocal简介

    线程本地变量,就是每个线程都有同一个变量的独有拷贝,下面看看其基本实现原理。

    其中常用的就是set/get方法了。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);
}
//它调用了getMap,getMap的代码为:
ThreadLocalMap getMap(Thread t){
	return t.threadLocals;
}

    返回线程的实例变量threadLocals,它的初始值为null,在null时,set调用createMap初始化,代码为:

void createMap(Thread t, T firstValue){
	t.threadLocals = new ThreadLocalMap(this,firstValue);
}

    从上面代码可以看出,每个线程都有一个Map,类型为ThreadLocalMap,调用set实际上是在线程自己的Map里设置了一个条目,键为当前的ThreadLocal对象,值为value。ThreadLocalMap是一个内部类,它是专门用于ThreadLocal的,与一般的Map不同,它的键类型为WeakReference,它与Java的垃圾回收机制有关,使用它,便于回收内存。

    get方法的代码为:

public T get(){
	Thread t = Thread.currentThread();
	ThreadLocalMap map = getMap(t);
	if(map!=null){
		ThreadLocalMap.Entry e = map.getEntry(this);
		if(e!=null)
			T result = (T)e.value;
			return result;
		}
	}
	return setInitialValue();
}

    通过线程访问到Map,以ThreadLocal对象为键从Map中获取到条目,取其value,如果Map中没有,则调用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;
}

    initialValue()就是提供初始值的方法,默认实现就是返回null。

    remove方法的代码如下。

public void remove(){
	ThreadLocalMap m = getMap(Thread.currentThread());
	if(m!=null)
		m.remove(this);
	}
}

    通过获得当前线程,如果不为空,则调用map的remove方法删除。

    总结下,每个线程都有一个Map,对于每个ThreadLocal对象,调用其get/set实际上就是以ThreadLocal对象为键读写当前线程的Map,这样,就实现了每个线程都有自己的独立副本的效果。1

    使用场景:日期处理、随机数和上下文信息。


  1. Java编程的逻辑 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值