温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

ThreadLocal不调用remove方法会导致业务逻辑错误的示例分析

发布时间:2021-11-12 16:48:14 来源:亿速云 阅读:139 作者:柒染 栏目:大数据

这篇文章给大家介绍ThreadLocal不调用remove方法会导致业务逻辑错误的示例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

为什么会导致业务逻辑出错:

当ThreadLocal用于线程池、web应用或者线程被多次重复使用的时候,特别要注意,以web应用为例:

我们都知道web应用很多类都是单例模式,如spring默认注入方式所创建的类就是一个单例,当不同的http请求到达服务器的时候,实际上都是使用了同一个实例,假如该实例使用了全局变量,当请求A修改了这个变量,后面到来的其它请求(此时不管A请求是否结束),如请求B再使用该变量的时候,实际上是被请求A修改过的,这会导致业务逻辑出错,而且很难被发现,这种情况,通常是使用ThreadLocal来解决,因为不同的请求虽然使用了同一个实例,但所使用的线程却不同,但有一点需要特别注意,那就是web容器的线程是重复使用的,web容器使用了线程池,当一个请求使用完某个线程,该线程会放回线程池被其它请求使用,这就导致一个问题,不同的请求还是有可能会使用到同一个线程(只要请求数量大于线程数量),而ThreadLocal是属于线程的,如果我们使用完ThreadLocal对象而没有手动删掉,那么后面的请求就有机会使用到被使用过的ThreadLocal对象,如果一个请求在使用ThreadLocal的时候,是先get()来判断然后再set(),那就会有问题,因为get到的是别的请求set的内容,如果一个请求每次使用ThreadLocal,都是先set再get,那就不会有问题,因为一个线程同一时刻只被一个请求使用,只要我们每次使用之前,都设置成自己想要的内容,那就不会在使用的过程中被覆盖。使用ThreadLocal最好是每次使用完就调用remove方法,将其删掉,避免先get后set的情况导致业务的错误。

例子:

分库 有3个库 db1 db2 db3

web应用使用了线程池 假如有10个线程

request1请求到达web服务端的时候,经过分库逻辑处理后,定位到的是db1,tomcat线程池分配的线程号是thread1,在给予thread1线程的threadlocal.set 保存的数据源是db1

由于tomcat线程池的线程是复用的,request2 恰巧tomcat给予该请求分配到的也是threade1,如果此时针对request2的请求,是不走分库逻辑的,用到的是配置死的db2数据源,那么此时就会导致request2用到的是上个处理请求request1的thread1里面的threadlocal的数据源db1,此时就会导致逻辑错误,找不到相应的表的错误

关于ThreadLocal不调用remove方法会导致业务逻辑错误的示例分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI