spring的ThreadLocal解决线程安全

参考资料:https://www.bilibili.com/video/BV1Ki4y1t7Va?t=4507

1.spring项目在开发过程中用的都是数据库连接池,这样可以避免线程的消耗,

之前说过spring的事务问题,事务保证了操作的一致性,那么线程安全是怎么保证的呢?

 

 底层用的ThreadLocal来保证线程之间的数据隔离

当一个线程开启事务时,会从连接池取一个连接 放到与自己绑定的ThreadLocal中,这个线程在service和dao层中获取连接时直接从ThreadLocal中获取,最后执行完了会把连接放回到线程池中。

源码:查看spring事务管理的DataSourceTransactionManager类的doBegin方法。

 

 

然后

 

 点开resources,发现是一个ThreadLocal对象

 

再点发现这个NameThreadLocal类继承自ThreadLocal,只是多了一个名字。

 

 这个类在spring中哪里用了呢?可以看到,spring中大量使用了ThreadLocal

 注:ThreadLocal是跟线程(通过线程id)绑定的,ThreadLocal是用来暂时存放数据的。

用法如下,在很多的登录安全框架中就是用的ThreadLocal来保存用户信息,如:security,因此在获取用户信息的时候才能获取当前线程对应的ThreadLocal对应的用户信息,

通过ThreadLocal来隔离用户信息,ThreadLocla是每个线程的实例,因此每个线程的ThreadLocal内容都是不一样的,spring通过ThreadLocal实现线程之间隔离,通过

单例模式来减少资源的消耗。

 在我的项目中,ThreadLocal和session是传递用户信息的:

流程如下:

 

 

 

 

 配置过滤器,在过滤器中从session中获取用户信息,然后存到ThreadLocal中,所以同一个线程获取的用户信息是一样的,因为session在同一客户端也是一样的,所以不同线程之前也能共享同一个用户信息。

注意理解request请求,session,以及生命周期:

每一个request就是一个线程,在web项目中这些个线程都是由Tomcat线程池管理,一次请求结束后request的生命周期也就结束了,

要延长request的生命周期可以用forward,但是redirect不行。

而Session是整个会话期间,注意,不同客户端的创建session的时候返回的JSESSIONID是不一样的,这就说明session也是不一样的,

session在服务器中是以session列表的形式存在的。

 

posted @ 2020-05-09 14:19  ~笑春风~  阅读(4087)  评论(0编辑  收藏  举报