程序员冈刀,目前就职于阿里,java开发工程师,研究生。2022年,毕业于北京邮电大学电子工程学院、电子与通信工程专业。个人公众号《代码废柴》欢迎关注。
大家好,我是默默无闻的程序员,后端开发工程师。今天分享一下java 里面的ThreadLocal的相关技术问题。之前分享过ThreadLocal的相关知识点,下面是之前分享的文章:
文章一:使用ThreadLocal的思考
文章二:ThreadLocal实现原理
正文开始
今天分享内容主要是ThreadLocal使用不当造成程序的BUG。看一看下面的问题描述:
它的问题是前后端参数传递的问题,前端传递了参数值,但是后端真正使用的地方,没有获取到这个参数值,所以爆出了一个NPE的错误。随后,他对自己的代码流程进行了分析,得到下面的结果:
实际上,产生上面的问题主要问题是ThreadLocal保存的数据是本线程的数据。如果跨线程获取参数,实际上是根本获取不到的,这才是问题的根本原因。
他后面解决的问题,是在真正需要获取参数的时候,先取出,然后再使用。如下所示:
虽然这样可以解决暂时的问题,但是不会解决根本的问题,因为设置在TheadLocal的本地参数说不定其他的位置还会进行使用,造成相同的问题,那么怎么解决这个问题呢?我建议的解决方式是,不采用原有自带的线程池执行这个代码逻辑,使用自定义线程池来执行你自己的任务。具体实现如下:第一步:首先定义一个上下文的工具类。
第二步:定义执行的Task
如上图,在业务真正执行之前,设置本线程的上下文,然后,就可以获取调用线程的上下文数据了。同理,callable对象相同的定义。
第三步:自定义线程池
如上图,要的操作是在提交任务的时候,提交的任务是自定义的task即可!
至此,已经定义完毕整个的过程,一起来测试一下吧!
可以从上图看得到,线程内部可以获取到在线程外部设置的值信息。遂,我们实现了从一个线程取到其他线程设置的值。
后序
实际上,在公司写代码,维护了同一线程池,也存在着线程之间信息断掉的情况,也是采用相同的方式实现的。今天突然看到这个问题,恰好是公司遇到的问题,遂写本文!!
这位小伙伴的文章:我麻了,ThreadLocal竟然获取不到值(大坑)
程序员冈刀,目前就职于阿里,java开发工程师,研究生。2022年,毕业于北京邮电大学电子工程学院、电子与通信工程专业。个人公众号《代码废柴》欢迎关注。