每一个
Thread
对象均含有一个
ThreadLocalMap
类型的成员变量
threadLocals
,它存储本线程中所 =有ThreadLocal
对象及其对应的值 ThreadLocalMap 由一个个
Entry
对象构成 Entry 继承自
WeakReference<ThreadLocal<?>>
,一个
Entry
由
ThreadLocal
对象和
Object
构 成。由此可见, Entry
的
key
是
ThreadLocal
对象,并且是一个弱引用。当没指向
key
的强引用后,该 key就会被垃圾收集器回收 当执行set
方法时,
ThreadLocal
首先会获取当前线程对象,然后获取当前线程的
ThreadLocalMap
对 象。再以当前ThreadLocal
对象为
key
,将值存储进
ThreadLocalMap
对象中。
get
方法执行过程类似。
ThreadLocal
首先会获取当前线程对象,然后获取当前线程的
ThreadLocalMap
对象。再以当前
ThreadLocal
对象为
key
,获取对应的
value
。
由于每一条线程均含有各自
私有的
ThreadLocalMap
容器,这些容器相互独立互不影响,因此不会存在
线程安全性问题,从而也无需使用同步机制来保证多条线程访问容器的互斥性。
使用场景:
1
、在进行对象跨层传递的时候,使用
ThreadLocal
可以避免多次传递,打破层次间的约束。
2
、线程间数据隔离
3
、进行事务操作,用于存储线程事务信息。
4
、数据库连接,
Session
会话管理。
ThreadLocal
内存泄露原因,如何避免
内存泄露为程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露
堆积后果很严重,无论多少内存
,
迟早会被占光,
不再会被使用的对象或者变量占用的内存不能被回收,就是内存泄露。
强引用:使用最普遍的引用
(new)
,一个对象具有强引用,不会被垃圾回收器回收。当内存空间不足,
Java
虚拟机宁愿抛出
OutOfMemoryError
错误,使程序异常终止,也不回收这种对象。
Spring
框架在事务开始时会给当前线程绑定一个
Jdbc Connection,
在整个事务过程都是使用该线程绑定的
connection
来执行数据库操作,实现了事务的隔离性。
Spring
框架里面就是用的
ThreadLocal
来实现这种 隔离