赞
踩
目前要学的东西太多,学过的东西遗忘的也多,没有懂得东西也多。不管了还是赶进度,然后再复习,对于重要的地方最后再来回顾。
用于不同线程下存储共享的数据变量,线程开启时接收当前的共享变量,其他线程开启时也可以接收,他们之间不会影响并且该threadLocal会作用在整个线程生命之间,也就意味着无论线程执行到哪一个代码类都能获取到存储的属性,相当于线程创建的属性,可用在该线程所要执行的任何对象的方法上获取,如前端请求开启线程-》controller-》service-》dao都是线程要执行的地方,而线程开启时创建了过Threadlocal则后继的执行的类区域都能获取到线程的ThreadLocal的存储对象,而且线程与线程之间不会干扰,如在拦截器里拦截请求获取前端的参数值放入该拦截器的ThreadLocal中,在并发的时候,每个开启的线程都会执行到各自的拦截器创建各自的threadLocal,接收前端相同的变量,到线程内部时这个变量在多线程中互不干扰,同一个线程上下文可以任何类内的任何方法获取。
原理:
当对象set的时候会获取当前线程对象的t.threadLocals属性,它是线程的属性ThreadLocal.ThreadLocalMap threadLocals = null;然后在在set中返回ThreadLocalMap对象,为null就创建,不为null就设置值,值的类型是泛型,也就是ThreadLocal的数据存取是通过ThreadLocalMap类实现的,它是一个map,解决散列冲突使用开放寻址、而hashmap使用的是分离链表法(或者是拉链法),ThreadLocalMap的key是一个弱引用,垃圾回收器会回收,导致key为null,对应存取的值引发内存泄漏。
- public void set(T value) {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null)
- map.set(this, value);
- else
- createMap(t, value);
- }
-
- void createMap(Thread t, T firstValue) {
- t.threadLocals = new ThreadLocalMap(this, firstValue);
- }
-
- ThreadLocalMap getMap(Thread t) {
- return t.threadLocals;
- }
应用使用ThreadLocal给客户端发放临时user-key保存在浏览器中,当添加购物车请求时执行拦截器,就会创建一个ThreadLocal对象并关联到当前线程,当添加购物车时判断用户是否登陆,登陆购物车的保存以用户id为key商品的skuId为键对象序列化为值,如果没有登陆就生成一个临时user-key保存商品信息,保存完成后通过设置cookie来记录当前为登陆的用户凭证,当未登录用户再次请求时,我们获取请求的所有cookie遍历获取user-key为键的id值,再去查redis并返回购物车内容,如果登陆了就直接添加用户的购物车,通过ThreadLocal每个线程就会处理各自用户的临时user-key,如果一个临时用户对该商品重复加入购物车,在判断该用户下的该商品获取不为空后,需要额外转外CartVo并对它的数量加1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。