当前位置:首页 > 技术 >

threadlocal底层原理(ThreadLocal原理)

来源:原点资讯(www.yd166.com)时间:2023-04-15 23:51:07作者:YD166手机阅读>>

引言

这是JWT认证条件下的getCurrentLoginUser代码实现,请分析性能:

在生产环境中,currentLoginUser永远为null,if不执行。

执行else内的解析JWT的代码,解析userId,再查询用户。

很明显,一次请求内,当getCurrentLoginUser被多次调用时,会重复解析JWT,就会产生性能问题。

解决

分析

解决重复解析JWT的唯一思路就是缓存,第一次解析完userId并查询出user后将这个user对象缓存。

因为并发请求时,每个请求分配一个线程管理Socket。

所以当前待解决的问题就变成了:如何设计一种缓存,使之各线程不影响,线程安全。

threadlocal底层原理,ThreadLocal原理(1)

简单的设计如上,一个Map,Thread作为key,用户缓存作为value。

ThreadLocal

ThreadLocal是啥?没听说过是不是?其实这是Java里最基础的东西。我的Java到底学了个啥呀?

日常吐槽,我发现其他学校竟然讲spring-boot、spring-cloud、ConcurrentHashMap源码,人家上完专业课直接精通kafka。

一般人知道HashMap的阀值为什么是8吗?

对不起,这些人家老师都讲过。而《河北工业大学》的“大博士”,你讲个检查异常都讲错了,被学生指出之后还不改。你去学学Java再来讲课好吗?

最后的结果就是,我们辛辛苦苦准备了好几个月的东西,人家课上就精通完了。怪不得干不过人家,我们引以为傲的spring-cloud、RPC原来都属于课上的基础知识。

继续。

我们想用一个类似Map<Thread, User>这样的数据结构来设计缓存,其实JDK中早就为我们封装好了,即ThreadLocal<T>。

栗子

大家来看下面的示例代码:

运行结果如下:

threadlocal底层原理,ThreadLocal原理(2)

main线程创建ThreadLocal对象,thread1、thread2操作的是同一个对象local,thread1、thread2分别set数据,两线程再次从local中获取数据的时候,能够保证两者数据不冲突。

底层原理

ThreadLocal中的set方法实现如下:

获取当前线程,同时通过线程对象获取ThreadLocalMap。

set内调用了getMap方法,看看getMap的内部实现:

返回线程对象内的threadLocals属性。

Thread类中的成员属性threadLocals,默认为null。

threadlocal底层原理,ThreadLocal原理(3)

接着看:获取到了Map之后,用当前的ThreadLocal对象作为key存储value进Map。

这样设计十分地精妙,每一个线程都有独立的Map存储,肯定能做到数据隔离且安全。且可方便地创建多个安全的ThreadLocal进行存储。

改写

鉴于ThreadLocal的特性,我们可以设计一个SecurityContext以封装ThreadLocal<User>。

写一个拦截器,思路如下:

在pre里解析JWT,并存到SecurityContext里。

在post里clear,防止线程池线程复用导致数据错误。

然后原来的getCurrentLoginUser方法直接从SecurityContext中get即可。

熟悉吗?

看到SecurityContext这个名称是不是很熟悉?

从spring-security中获取用户信息的方法如下,它怎么实现的呢?

点开spring-security源码,有三种策略:GlobalSecurityContextHolderStrategy(即全局线程共享策略)、ThreadLocalSecurityContextHolderStrategy(本地策略)、InheritableThreadLocalSecurityContextHolderStrategy(可继承的本地策略)。

threadlocal底层原理,ThreadLocal原理(4)

点开源码后发现,其实spring-security就是这么简单,内部也是用ThreadLocal实现的,只是此处存储的信息比较多,使用ThreadLocal<SecurityContext>。

栏目热文

threadlocal用法示例(threadlocal使用场景)

threadlocal用法示例(threadlocal使用场景)

1.ThreadLocal的使用场景1.1 场景1每个线程需要一个独享对象(通常是工具类,典型需要使用的类有Simple...

2023-04-15 23:54:10查看全文 >>

threadlocal使用场景(threadlocal不能使用的场景)

threadlocal使用场景(threadlocal不能使用的场景)

推荐学习 前言相信很多同学都听过threadLocal,即使没用过也听过。但是要仔细一问ThreadLocal是个啥,...

2023-04-15 23:59:17查看全文 >>

threadlocal为什么是弱引用(threadlocal为什么是安全的)

threadlocal为什么是弱引用(threadlocal为什么是安全的)

前言大家好,我是捡田螺的小男孩。无论是工作还是面试,我们都会跟ThreadLocal打交道,今天就跟大家聊聊Thread...

2023-04-15 23:32:30查看全文 >>

threadlocal使用实例(threadlocal例子)

threadlocal使用实例(threadlocal例子)

如何统计时间说着说着,慧能写了一段程序说着说着一尘就随手写了一段程序经验丰富的慧能一眼就看出来这个程序的致命缺陷这个程序...

2023-04-15 23:18:30查看全文 >>

threadlocal的缺点(threadlocal应用场景)

threadlocal的缺点(threadlocal应用场景)

在 Java 中,如果要问哪个类使用简单,但用好最不简单?我想你的脑海中一定会浮现出一次词——“ThreadLocal”...

2023-04-15 23:39:40查看全文 >>

threadlocal 使用场景(threadlocal详细介绍)

threadlocal 使用场景(threadlocal详细介绍)

两大使用场景-ThreadLocal的用途典型场景1: 每个线程需要一个独享的对象(通常是工具类,典型需要使用的类有Si...

2023-04-15 23:45:51查看全文 >>

threadlocal实例(threadlocal使用范例)

threadlocal实例(threadlocal使用范例)

作者:@adamhandzybuluo.com/adamhand/note/1370920ThreadLocal是什么首...

2023-04-15 23:56:45查看全文 >>

threadlocal的底层原理(threadlocal实际中的作用)

threadlocal的底层原理(threadlocal实际中的作用)

1、ThreadLocal的底层原理图说明:Thread中有threadLocals成员变量,threadLocal会在...

2023-04-15 23:59:19查看全文 >>

threadlocal 存在意义(threadlocal存在哪里)

threadlocal 存在意义(threadlocal存在哪里)

功能迭代,在代码层面小编有1w种实现方法(吹牛的),一起来看看这次小编如何使用ThreadLocal优雅地完成本次迭代吧...

2023-04-15 23:15:22查看全文 >>

javathreadlocal原理(java thread 方法详解)

javathreadlocal原理(java thread 方法详解)

图解:该图基于Android中的ThreadLocal在Looper中的应用,其能够实现一个线程只有一个Looper的私...

2023-04-15 23:23:59查看全文 >>

文档排行