ThreadLocal
- 一、ThreadLocal概述
- 二、ThreadLocal解决并发时的线程不安全问题
- 三、ThreadLocal的工作原理
一、ThreadLocal概述
ThreadLocal 是一个线程变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,例如A线程和B线程都想使用一个变量,此时就存在竞争资源的问题,而这个变量他可以有多份,此时就可以用ThreadLocal作为变量的管理者 ,不存在多线程隐患.。同时它隐式的可以作为一个线程内部的传递信息的一个工具。
ThreadLocal的特点包括线程本地化存储、简化线程安全编程、避免多线程共享状态等。
二、ThreadLocal解决并发时的线程不安全问题
ThreadLocal从另一个角度来解决线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。例如在多线程中都去使用一个对象,但是又希望互不干涉,此时就需要用到ThreadLocal。实现线程间数据的隔离,保证各个线程之间的数据独立存储,同时也能实现某些数据的共享和传递
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
三、ThreadLocal的工作原理
ThreadLocal是作为当前线程属性ThreadLocalMap集合中的某一个Entry的key值Entry(threadLocal,value),虽然不同的线程之间threadlocal这个key值是一样,但是不同的线程所拥有的ThreadLocalMap是独一无二的,也就是不同的线程间同一个ThreadLocal(key)对应存储的值(value)不一样,从而到达了线程间变量隔离的目的,但是在同一个线程中这个value变量地址是一样的。
//ThreadLocal中主要使用下面四个方法 get set remove withInitial(初始化方法 相当于 new ThreadLocal() )public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {map.set(this, value);} else {createMap(t, value);}}public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}private T setInitialValue() {T value = initialValue();Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);return value;}public void remove() {ThreadLocalMap m = getMap(Thread.currentThread());if (m != null) {m.remove(this);}}
当通过 ThreadLocal 的 set 方法设置变量时,实际上是通过当前线程的ThreadLocalMap 将 ThreadLocal 与值关联起来。
当通过 ThreadLocal 的 get 方法获取变量时,实际上是通过当前线程的ThreadLocalMap 查找与之关联的值。
ThreadLocalMap 使用 ThreadLocal 的弱引用作为 key,以防止内存泄漏。当 ThreadLocal 被回收时,对应的映射关系也会被清理。