ThreadLocal(线程本地存储)
ThreadLocal,即线程本地变量或线程本地存储。
Threadlocal相当于一个容器,用于存放每个线程的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。Threadlocal实例通常来说都是public static类型的。Threadlocal可以给一个初始值,而每个线程都会获得这个初始值的一个副本,这样才能保证不同的线程都有一份拷贝。
一般情况下,通过Threadlocal.set()到线程中的对象是该线程自己使用的对象,其他线程是访问不到的,各个线程中访问的是不同的对象。如果Threadlocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的Threadlocal.get()取得的还是这个共享对象本身,还是有并发访问问题。
向Threadlocal中的set的变量是由Thread线程对象自身保存的,当用户调用Threadlocal对象的set(Object o)时,该方法则通过Thread.currentThread()获取当前线程,将变量存入线程中的ThreadlocalMap类的对象内,Map中元素的键为当前的Threadlocal对象,而值对应线程的变量副本。
ThreadLocalMap(就是线程中的一个属性)
每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。
将一个共用的Threadlocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中,然后在线程执行的各处通过这个静态Threadlocal实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。
ThreadLocalMap其实就是线程里面的一个属性,他在thread类中定义。
ThreadLocal.ThreadLocalMap threadLocals=null;
public T get(){
Thread t = Thread.currentThread();//每个Thread对象内部保存一个ThreadlocalMap对象。
ThreadlocalMap map = getMap(t);//map重元素的键为共用的Threadlocal对象,而值为对应线程的变量副本。
if(map != null)
return (T)map.get(this); T value = initialValue();
createMap(t,value);
return value;
} public void set(T value){
Thread t = Thread.currentThread();
ThreadlocalMap map = getMap(t);
if(map != null)
map.set(this,value);
else
createMap(t,value);
} ThreadlocalMap getMap(Thread t){
return t.threadLocals;
} void createMap(Thread t, T firstValue){
t.threadLocals = new ThreadlocalMap(this,firstValue);
}
使用场景:
最常见的threadlocal使用场景是用来解决数据库连接、session管理等。
private static final ThreadLocal threadSession = new ThreadLocal();
public static Session getSession() throws InfrastructureException {
Session s = (Session) threadSession.get();
try {
if (s == null) {
s = getSessionFactory().openSession();
threadSession.set(s);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return s;
}
最新文章
- 假装有题目 &; Trie+贪心
- vsfptd
- CSS Clip剪切元素动画实例
- 创Wcf案例数据服务
- 最短路问题之Dijkstra算法
- Linux -- Centos6 yum安装相关问题与处理
- 2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017)
- 面向对象之反射 与__str__等内置函数
- UITableView 滚动到最后一行
- 面试题13:在O(1)时间删除链表节点
- springBoot----@ConditionalOnxxx相关注解总结
- EXEC与sp_executesql的区别及应用
- bzoj1296【SCOI2009】粉刷匠
- File Path Directory总结
- TCP 的那些事儿-1
- Java类的实例化的初始化过程
- Win10启动盘制作工具
- 842. Split Array into Fibonacci Sequence
- unity, PlayerPrefs.GetInt(key,defaultValue)
- day11函数的进阶动态参数,命名空间,作用域,第一类对象
热门文章
- GitLab CI/CD持续集成设置
- Java描述设计模式(12):外观模式
- python文件夹遍历,文件操作,获取文件修改创建时间
- Oracle数据库之第三篇
- CAD简易口诀,保你一天就记住!零基础也能轻松学!CAD制图宝典!
- mysql登陆时出现ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0
- 【转载】作为Android开发者,你真的熟悉Activity吗?
- iOS多线程定时器
- Horovod 分布式深度学习框架相关
- python配置yaml