• 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列表的形式存在的。

    我不是程序员,我只是程序的搬运工
  • 相关阅读:
    grep命令详解;单引号和双引号区别(转载)
    Linux下的系统性能调优工具--Perf (转载)
    Shiro
    WebLogic和Tomcat
    MD5加密(java和c#)
    深入理解java泛型
    VS2015常用快捷键总结(转)
    Java 反射 使用总结
    @RequestParam与@PathVariable的区别
    SVN被锁定的几种解决方法
  • 原文地址:https://www.cnblogs.com/keith0/p/12857179.html
Copyright © 2020-2023  润新知