1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
从上面的示例可以看出,在不同的线程中对ThreadLocal变量进行set和get操作时,它们的变量是相互独立的.
为什么ThreadLocal能实现线程变量隔离
从源码中可知,每一个Thread内部都有一个ThreadLocalMap,ThreadLocalMap里面 Key是当前ThreadLocal对象,Value是线程对应的变量副本,ThreadLocal所做的事情就是 负责维护每个Thread内部的ThreadLocalMap.
ThreadLocal的核心方法
T get(); // 获取本地线程变量
void set(T value) // 设置本地线程变量
void remove(); // 移除本地线程变量
1
2
3
get()的执行内容:
1. 根据Thread.currentThread() 获取当前执行线程信息,并根据当前线程对象获取该线程的ThreadLocalMap对象
2. 若map不为空,直接根据当前ThreadLocal对象获取entry,进入过去value副本并返回
3. 若map为空,将线程变量副本写入null,并返回null.
set()的执行内容:
1. 根据Thread.currentThread() 获取当前执行线程信息,将ThreadLocal对象和值写入到当前线程对应的map中.
3. 若map为空,则需要初始化当前线程的ThreadLocalMap对象,再写入ThreadLocal和value的副本.
remove()的执行内容:
1. 获取当前线程的ThreadLocalMap并移除Key为当前ThreadLocal对象的键值对.
ThreadLocal的问题(可能内存泄漏)
当ThreadLocal存储了很多 Key = null 的Entry时,但长时间不结束当前thread 且不再调用get(),set(),remove() 方法,那么当ThreadLocal对象被回收后,Key是弱引用也被回收,但是Value是强引用,一直不回收,就容易导致内存泄漏.
如何解决该问题: 每次调用完ThreadLocal之后,都调用remove()方法,手动销毁数据.
ThreadLocal带来的好处
ThreadLocal把操作的数据存储在了线程本地,直接本地内存读取,不再需要synchronized等同步的方式修改主内存的数据,然后再复制到本地内存,提高了访问效率. 这也是为什么ThreadLocal能解决线程安全的问题.
ThreadLocal和线程同步的一些异同: 同步机制采用了“以时间换空间”的方式: 串行访问数据,并共享对象. 而ThreadLocal采用了“以空间换时间”的方式: 并行访问,独享对象.
主要应用场景
在维护每个线程的Session的时候,ThreadLocal能帮助我们在每个线程中独享资源.
数据库连接在多线程读取的时候,使用ThreadLocal包装,能将线程和数据库连接绑定,方便事务操作.
---------------------
作者:朝夕夕夕夕
来源:CSDN
原文:https://blog.csdn.net/wau_hua/article/details/85067292
版权声明:本文为博主原创文章,转载请附上博文链接!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。