在学习javaweb阶段经常会用到ThreadLocal,但是threadlocal应该在什么情况下用呢?它和一次会话有什么关系呢?它和线程之间的关系是什么呢?应该在哪里用呢?为什么要在那里用呢?为什么不用session存取呢?为什么不选择从请求头中获取token再去redis中获取呢?源码结构是什么呢?有什么注意事项呢?初学者对于这些问题会很疑惑,通过阅读源码与查阅相关资料,在这里写一些小小的见解。
- 什么情况下用:保证每次http请求即每条线程安全,降低代码的重复。
- 和一次会话的关系,和线程之间的关系:一次会话会发起很多次请求,每一次http请求都会从tomcat线程池中拿一条新的线程,而每一条线程中可以有多个threadlocal对象
- 在哪里用:因本人接触的业务有限,目前都还只是在拦截器中使用
- 为什么在拦截器中使用:在web的初始阶段,很多人分不清会话和线程之间的关系,会认为一次会话就是一条线程,导致初学者认为应该在登录成功的界面使用threadlocal,但这样其实是错误的。因为登录完成后,这条线程就归还给tomcat了,当有新的请求被发起时,这条线程里没有任何数据的。而在拦截器中使用的话,都是属于同一个线程,可以共享数据。
- 为什么不用session存取/为什么不选择从请求头中获取token再去redis中获取:
1.httprequest和session属于springMVC的,在其他层面用不够规范,也不优雅。
2.httprequest和session不安全。
3.如果存储的数据在其他线程会被频繁使用,比如user,那么在每个其他功能都先获取请求头,在获取token,再用token获取user,大大增加了代码的重复,所以也不推荐。
- 源码结构:通过分析threadlocal的源码可以知道,threadlocal里面维护了一个map,键是this,就是当前的threadlocal对象,值是存入的数据。
- 注意事项:threadlocal使用完再手动remove,为了避免线程归还连接池的时候还存留数据,导致其他请求使用到该数据
----------------------------------------------------分割线-------------------------------------------------------------------
在微服务中的新的见解