ThreadLocal并非是一个线程的本地实现版本,首先它并不是一个Thread,而是 threadLocalvariable(线程局部变量),简单的理解就是:为每一个使用该变量的线程提供变量值的副本,是JAVA中一种特殊的线程绑定机制。
1:从线程的角度来看:每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal实例时可访问的,那么在线程消失之后,其线程局部实例的所有副本都会被垃圾回收器回收
2:通过ThreadLocal存取数据,总是与当前线程相关,也就是说,JVM为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境出现的并发问题提供了一种隔离机制,它采用空间换时间的方式,来保证同时访问而不受影响。
3:ThreadLocal实现版
public class SimpleThreadLocal{
private Map valueMap = Collections.synchronizedMap(new HashMap());
/**
* 设置副本的值
* */
public void set(Object newValue) {
//①键为线程对象,值为本线程的变量副本
valueMap.put(Thread.currentThread(), newValue);
}
/**
* 获取副本的值
* */
public Object get() {
Thread currentThread = Thread.currentThread();
//②返回本线程对应的变量
Object o = valueMap.get(currentThread);
//③如果在Map中不存在,放到Map中保存起来。
if (o == null && !valueMap.containsKey(currentThread)) {
o = initialValue();
valueMap.put(currentThread, o);
}
return o;
}
/**
* 移除副本的值
* */
public void remove() {
valueMap.remove(Thread.currentThread());
}
/**
*
* */
public Object initialValue() {
return null;
}
}
4: ThreadLocal与同步机制有什么优势了?
在同步机制中,通过对象锁的机制,保证同一时间只有一个线程访问变量,这时该变量时多个线程共享的,那么使用同步机制需要程序缜密的分析,什么时候需要对变量进行读写,什么时候需要锁定对象,什么时候释放对象等繁杂问题,那么这会使程序的编写难度变大。
而ThreadLocal从另一个角度解决多线程的并发访问,因为ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突,因为每个线程都拥有自己的独立变量,所以就没有必要对该变量进行同步,所以在编写程序时,应该把不安全的变量封装进 ThreadLocal.
5: ThreadLocal实际使用
在Android Handler消息机制中,Looper.prepare() 就是通过ThreadLocal机制 将 当前线程和 Looper绑定。
在访问数据库时,建立数据库连接对象,就可以通过ThreadLocal将连接对象和线程绑定
在访问web服务器时,客户端和服务端生成Session 。也可以通过 ThreadLocal将Session和线程绑定