对线程本地变量的理解,将登录信息存放到线程本地变量中

      在获取用户的登录信息时,我们一般从ThreadLocalMap中获取,ThreadLocalMap中存放的变量就是线程本地的变量,是线程隔离的,使用线程本地变量而非局部变量的原因:方便我们对这些变量统一管理,免去频繁地传参。

ThreadLocal 原理:实质上,线程本地变量并不是存储在ThreadLocal中,而是存放在ThreadLocalMap中,ThreadLocalMap是ThreadLocal中的一个静态内部类,也是Thread中的一个成员变量,每个线程有每个线程自己的ThreadLocalMap,因此是线程隔离的,我们查看ThreadLocal的set(T value)源码可以看到:

对线程本地变量的理解,将登录信息存放到线程本地变量中_第1张图片

ThreadLocal执行set方法其实是当前线程的ThreadLocalMap对象执行set方法,key是线程的ThreadLocal对象,如果这个线程没有ThreadLocalMap对象则为它创建一个

对线程本地变量的理解,将登录信息存放到线程本地变量中_第2张图片

这里我们需要注意一下getMap方法,这是获取ThreadLocalMap。

我们再看一下ThreadLocalMap的键值对和它的set方法,首先是ThreadLocalMap的键值对接点Entry,通过源码得知它是一个键为ThreadLocal,值为Object对象的弱引用。

对线程本地变量的理解,将登录信息存放到线程本地变量中_第3张图片图为Entry的继承关系和构造函数

由于每个线程拥有不同的ThreadLocalMap对象,所以每个节点的数据是线程隔离的,每个线程对ThreadLocalMap的操作只能操作自己的变量。至于为什么Entry的key要继承弱引用呢:防止线程销毁后,key一直不被回收造成内存泄漏

通过代码实现将数据放入线程本地变量

/**
 * 将变量存到他自己的线程本地变量
 * 
 * */
class ThreadLocalUtil{
	ThreadLocalUtil(){
		
	}
	/**
	 * 创建threadLocal对象 规定存入ThreadLocal中的数据类型
	 * */
	public static final ThreadLocal> threadLocal=new ThreadLocal>();
	public static HashMap get(){
		return threadLocal.get();
	}
	public static void set(HashMap payLoad) {
		 threadLocal.set(payLoad);
	}
	public static void remove() {
		threadLocal.remove();
	}
	
}
class TeatThread extends Thread{

	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		HashMap map=new HashMap();
		map.put(Thread.currentThread().getName(),Thread.currentThread().getName()+ "value");
		ThreadLocalUtil.set(map);
		System.err.println(Thread.currentThread().getName()+"------"+ThreadLocalUtil.get().get(Thread.currentThread().getName()));
	}
	
}
public class hellojava {
	public static void main(String[] args) {
		TeatThread t1=new TeatThread();
		t1.setName("t1");
		TeatThread t2=new TeatThread();
		t1.setName("t2");
		t1.start();
		t2.start();
		}
}

 

你可能感兴趣的:(对线程本地变量的理解,将登录信息存放到线程本地变量中)