一、ThreadLocal的理解
ThreadLocal是java中比较特殊的线程绑定机制,为每一个使用该变量的线程创建一个变量的副本,并且每一个线程都可以独立地使用自己的副本,相互不影响。
一般如果某个线程要被某个单独变量使用,那么ThreadLocal可以用来实现线程的本地存储。
JDK中说到: ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread ( e.g., a user ID or Transaction ID ).
在单例设计模式中做到线程安全的懒汉设计模式,除了双锁检查,其中就用到了ThreadLocal。设计代码如下
public class Singleton {
// ThreadLocal 线程局部变量,将单例instance线程私有化,单独被线程使用
private static ThreadLocal<Singleton> threadlocal = new ThreadLocal<Singleton>();
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
// 第一次检查:若线程第一次访问,则进入if语句块;否则,若线程已经访问过,则直接返回ThreadLocal中的值
if (threadlocal.get() == null) {
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查:该单例是否被创建
instance = new Singleton();
}
}
threadlocal.set(instance); // 将单例放入ThreadLocal中
}
return threadlocal.get();
}
}
1、那么一般来说每个变量都有自己的TheadLocal变量的私有值
2、独立于最初的变量初始值
3、将某个类的状态与线程相关联
二、源码上看ThreadLocal
可以看出有四个方法:get()、set(T value)、remove()、initialValue()
/**
* Create the map associated with a ThreadLocal. Overridden in
* InheritableThreadLocal.
*
* @param t the current thread
* @param firstValue value for the initial entry of the map
* @param map the map to store.
*/
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue); // this 指代当前 ThreadLocal 变量,为 map 的键
}1234567891011
- **每个线程内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals存储了与该线程相关的所有的ThreadLocal变量及所对应的值。**如上面源码所示,ThreadLocal变量及其对应的值就是该Map中的一个Entry.
- 初始化时,ThreadLocals为空,但是可以调用get和set方法对ThreadLocals进行填充,这时候TheadLocal为key值,所要保存的值为value。
- 然后在当前线程中,使用ThreadLocal对象,也是可以通过get方法来获得线程的threadLocals,然后在取得对应的value。
三、 ThreadLocal使用步骤
1、创建ThreadLocal对象Threadxxx,然后绑定线程所需要单独处理的对象。
2、提供一个获取访问隔离对象的get()方法,在方法中判断,如果ThreadLocal对象为null的时候,应该new()一个隔离访问类型的对象;
3、在线程的run()方法中,通过get()方法来获取要操作的数据,可以保证每个线程一个数据对象,在任何时刻都操作这个对象。
参考博客