五分钟深入理解 ThreadLocal

五分钟深入理解 ThreadLocal如果把 ThreadLocal 改成 ThreadLocalVariable 或许更容易理解,和 Integer Double 一样,是基本数据

大家好,欢迎来到IT知识分享网。

如果把 ThreadLocal 改成 ThreadLocalVariable 或许更容易理解,和 Integer Double 一样,是基本数据类型的封装类型,只不过它是一个用在 Thread 内的 Variable,

在不同的线程中访问同一个 ThreadLocal 对象的 set 和 get 进行存取数据是不会相互干扰的。ThreadLocal就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)

五分钟深入理解 ThreadLocal

ThreadLocal 源码的数据类型

Java 常用的数据类型里,ThreadLocal 肯定是其中的一种,如果让你盲猜你会想到什么,我猜是个Map,现在我们看看源码,我盲搜Map关键字看出来什么?

五分钟深入理解 ThreadLocal

内部使用的是 Entry 数组,我就当HashMap使用。

ThreadLocal 的使用场景

可能很多人不知道 ThreadLocal 的使用场景,只是为了背面试题而背,这就尴尬了,工作中,只要有线程的地方就可以使用 ThreadLocal 就像使用 Integer 一样自然。

ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。

比如缓存用户登陆信息:

我有一个全局拦截器,在拦截器里校验每一次用户身份是否合法。

@Slf4j @Service public class UcRequestContext extends HandlerInterceptorAdapter { private static final ThreadLocal<SessionUser> SESSION_USER_THREAD_LOCAL = new ThreadLocal<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { PermissionParamConfig permissionParamConfig = applicationContext.getBean(PermissionParamConfig.class); // 构建 session 信息 SessionUser session = new SessionUser() // 省略 session set 方法 SESSION_USER_THREAD_LOCAL.set(session); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 清空session SESSION_USER_THREAD_LOCAL.remove(); } } 

每次一请求开始,代表一个新的Thread创建,preHandle会创建一个 ThreadLocal 方法,

每次一请求结束,代表一个新的Thread创建,afterCompletion会销毁这个 ThreadLocal 里的session信息。

ThreadLocal 在 JDK 8 中 做了哪些升级

 static class ThreadLocalMap { /** * The entries in this hash map extend WeakReference, using * its main ref field as the key (which is always a * ThreadLocal object). Note that null keys (i.e. entry.get() * == null) mean that the key is no longer referenced, so the * entry can be expunged from table. Such entries are referred to * as "stale entries" in the code that follows. */ static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } } } 

可以看到 ThreadLocalMap 中的 Entry 继承了 WeakReference<ThreadLocal<?>>

为什么是弱引用呢?

使用弱引用的原因在于,当没有强引用指向 ThreadLocal 变量时,它可被回收,从而避免上文所述 ThreadLocal 不能被回收而造成的内存泄漏的问题。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/46681.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信