这次想总结ThreadLocal这个东西,也是由于项目中使用到了它去帮助保存会话信息。传统的(或者说我在学校的时候)方法,大多是用服务端的session保存会话,与浏览器端的cookie协作去追踪这个会话。而现在更多的使用ThreadLocal去保存会话的信息,这是由于ThreadLocal天生带有线程安全的特性,并且仅仅在一个线程内共享变量(恰好符合多用户多会话请求这一场景),这就使得这种方式用起来十分顺手和简单。

1. 项目中的使用:

  首先记录一下项目中ThreadLocal是如何保存用户会话信息的:

     private final String KEY_USER = "user";
private final String KEY_TICKET = "ticket";
private final String KEY_ROLEKEY = "roleKey"; private static class Inner{
static LocalThreadUtils localThreadUtils = new LocalThreadUtils();
} public static LocalThreadUtils getInstance(){
return Inner.localThreadUtils;
} private ThreadLocal<Map<String, Object>> threadLocal = ThreadLocal.withInitial(() -> Maps.newHashMap()); public void cleanContext(){
threadLocal.get().clear();
}

  核心就是这样一个内部类的单例模式,产生的单例有一个theadLocal私有变量,用ThreadLocal修饰,内部是一个Map,而这个map可以由我们自己去存放用户的各种信息,比如ticket,角色role,用户信息user等。

  ThreadLocal这种方式的优点在于实现简单,并不需要我们在每一层传递request,也不用考虑httpSession的作用域,我们可以再任意层(controller,service等)直接访问当前线程信息,从而取出会话信息。

2. 实现方式和原理:

ThreadLocal类是如何为每个线程创建一个变量的副本的:

首先,在每个线程Thread内部有一个ThreadLocal.ThreadLocalMap类型的成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)。

初始时,在Thread里面,threadLocals为空,当通过ThreadLocal变量调用get()方法或者set()方法,就会对Thread类中的threadLocals进行初始化,并且以当前ThreadLocal变量为键值,以ThreadLocal要保存的副本变量为value,存到threadLocals。

然后在当前线程里面,如果要使用副本变量,就可以通过get方法在threadLocals里面查找。

其他想要说的:

ThreadLocal真的不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。 
1、每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。 
2、将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中,然后在线程生命周期内执行的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象,避免了将这个对象作为参数传递的麻烦。

  写在最后:这里只是对ThreadLocal做一个小小的总结,因为在之前的项目中从来没有真正使用过,只是字面上了解他的含义。很多知识确实要通过实践才能有更深刻的理解。

由会话信息保存认识ThreadLocal的更多相关文章

  1. Android将应用log信息保存文件

    相信大家在做应用调试的时候,不可能时时通过USB线连着电脑去查看log信息,所以,将应用的log信息保存到手机本地就很有必要了,有助我们从这些log信息中提取有用的部分,以解决一些bug,下面我把网上 ...

  2. LogcatHelperDemo【应用log信息保存成本地文件】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 简单记录下LogcatHelper的使用,并对原有代码进行了修改[因为保存到应用内的目录中不需要申请权限,所以去掉保存到SD的功能- ...

  3. SQL Server如何用触发器捕获DML操作的会话信息

    需求背景 上周遇到了这样一个需求,维护人员发现一个表的数据经常被修改,由于历史原因:文档缺少:以及维护人员的经常变更,导致他们对系统也业务也不完全熟悉,他们也不完全清楚哪些系统和应用程序会对这个表的数 ...

  4. DataGrid列表信息保存为EXCEL到指定的路径 ---------继续DataGrid在WPF的数据绑定

    一.许多WPF或者Winform程序在保存数据时,会以EXCEL或者文本的形式展现可视化界面的数据,本文就简单介绍下将DataGrid列表信息保存为EXCEL到指定的路径下,例子很简单,用的着的直接用 ...

  5. fiddler的安装与使用(二)使用fiddler捕获会话信息

    前章回顾: 上一遍文章我们已经安装好了fiddler,并解了fiddler的工作原理,接下来开始使用fiddler捕获浏览器会话信息. fiddler基本界面: 首先启动fiddler,然后打开浏览器 ...

  6. Where does Oracle SQL Developer store connections? oracle SQL Developer 连接信息保存的位置,什么地方

    oracle SQL Developer 连接信息保存的位置,在什么地方? 在切换登录用户后,oracle SQL Developer 连接信息不见了.只要以前的用户信息还存在,可以在路径 C:\Us ...

  7. tmux会话断电保存自动恢复

    tmux可以用于会话管理,通过建立session,可以保证当前设备和服务期断开连接之后,会话中的指令继续运行,非常适合用于执行需要长时间运行的任务. 但是tmux也有一个问题,那就是session在服 ...

  8. 会话过程保存数据对象cookie和session

    1 cookie是以键值对保存在浏览器端,服务器端可以创建.接收.发送 cookie 信息. request可以接收 cookie, response 可以发送 cookie. 1)cookie 可以 ...

  9. Django项目SECRET_KEY等敏感信息保存

    在我们做完django项目后,向生产环境部署时,为了避免一些敏感信息被有心人利用,我们应该将其保护起来,比如说在settings配置中的一些密码等内容存在操作系统内,通过调用来使用,比如下面这种做法: ...

随机推荐

  1. Windows Azure Storage (25) Azure Append Blob

    <Windows Azure Platform 系列文章目录> 在笔者之前的文章中,我们介绍了Azure Blob 有两种:Block Blob和Page Blob. 在这里笔者介绍Blo ...

  2. shared_ptr模版推导的问题

    问题描述 今天在帮同事解决问题时,发现了这个比较有意思的现象,特记录下来备忘. 问题是这样的,同事开发的是应用程序动态库模块,通过应用的框架中以接口方式供外部使用.然后他想对这些接口生命周期进行控制, ...

  3. 关于js 全选 反选

    prop 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. attr  对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. $("#selectAll ...

  4. gitlab项目迁移

    ALL Git* => Gitlab Nothing, Just copy the git URL to gitlab(类似于 fork) 使用 Git Mirror 無痛轉移 Git Serv ...

  5. MySQL创建用户与授权

    一. 创建用户 命令: CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 说明: username:你将创建的用户名 host:指定该用户 ...

  6. ajax请求中contentType与dataType区别

    contentType: 告诉服务器,我要发什么类型的数据,默认值: "application/x-www-form-urlencoded". dataType:告诉服务器,我要想 ...

  7. 捋一捋js面向对象的继承问题

    说到面向对象这个破玩意,曾经一度我都处于很懵逼的状态,那么面向对象究竟是什么呢?其实说白了,所谓面向对象,就是基于类这个概念,来实现封装.继承和多态的一种编程思想罢了.今天我们就来说一下这其中继承的问 ...

  8. 高可用之KeepAlived(2):keepalived+lvs

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  9. Nginx和php是怎么通信的?

    先来看一下搭建好PHP运行环境的Nginx配置文件. 非常重要的就是 fastcgi_pass 指令了,这个指令用于指定 fpm 进程监听的地址,Nginx 会把所有的 php 请求翻译成 fastc ...

  10. Scrum方法论

    产品负责人: 代表客户或未来游戏玩家.产品负责人需要确保所有有趣的功能都能在游戏中实现,还负责对游戏完整观感的理解. Scrum主管: 代表理性思维.需要主持每日Scrum会议,并确保每个人都在执行任 ...