ThreadLocal的基本定义是什么


这期内容当中小编将会给大家带来有关ThreadLocal的基本定义是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。官方释义:http://docs.oracle.com/javase/8/docs/api/
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances aretypically private staticfields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).首先,每个线程都有变量的一个本地独立副本,保证线程之间的数据不会互相影响可以通过重写initialValue()方法实现ThreadLocal的默认初始值为什么说明中建议定义为静态static方法呢?不了解ThreadLocal原理的同学可能就糊涂了,既然是需要满足多线程并发的,怎么会定义为一个静态的类成员变量呢?
只要大家看一下ThreadLocal的源码就了解了,它有个静态内部类叫ThreadLocalMap, 此Map在Thread类中被定义为了一个类成员变量,即每个Thread线程中都有一个独立ThreadLocalMap副本,它的值只能被当前线程读取和修改
想像一下某个类中定义了多个ThreadLocal>变量,在当前线程中通过ThreadLocalMap.get(ThreadLocal)获取到相应的变量副本。
所以ThreadLocal变量本身不是副本,你可以把他当成一个代理,而ThreadLocalMap中存放了线程内的一个一个线程副本,ThreadLocal只是ThreadLocalMap内弱引用的Key(在ThreadLocal对象失效时可以及时的清理ThreadLocalMap)。
这也回答了为什么ThreadLocal可以定义为static, 它只是Map中的Key而已,不同线程的Map副本获取同一个Key的值完全不会冲突。
继续延伸出一个问题: ThreadLocal类本身是线程安全的么?
通过源码看到不管是get,set还是createMap都没有做任何的同步或者并发锁。答案是安全的,因为实现都是基于当前线程的。在线程池复用的情况下,若ThreaLocal数据没有被清理掉,会被后面的请求复用然后拿到被你修改过的值!
之前在实现日志上下文LogContext的时候碰到了类似问题:请求A进入Controller中, 开启线程A,LogContext中记录了大量的ThreadLocal中间变量值,在请求响应结束后,请求线程A回归线程池;请求B进入Con 香港云主机troller中,复用线程A,LogContext会在之前变量值的基础上继续添加信息,这样的日志信息成了叠加的了。不管是基于自己实现的线程池,还是应用服务器(如Tomcat)的线程池,都需要小心这一点!
标准或者规范做法是在线程变量使用完毕之后,或者finally代码块中调用 threadLocalVariable.remove() 移除,以防被其他线程复用。上述就是小编为大家分享的ThreadLocal的基本定义是什么了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注开发云行业资讯频道。

相关推荐: MyBatis中大于号以及小于号的表达方式是怎样的

MyBatis中大于号以及小于号的表达方式是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。转义法大于:>小于:大于等于:>=小于等于:关于My 香港云主机Batis中大于号以…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 09/23 19:34
下一篇 09/23 19:34

相关推荐