ThreadLocal 相关分析,请查看http://wangxinchun.iteye.com/blog/1884228 
另外一个必须要提的点是: 
ThreadLocal在线程池环境下的使用。 
比如tomcat 提供的web http请求,一般都有线程池对请求做处理。

这种情况下要注意,并非每次web请求时候程序运行的ThreadLocal都是唯一的,ThreadLocal的生命周期不等于一次Request的生命周期,ThreadLocal与线程对象紧密绑定的,由于Tomcat使用了线程池,线程是可能存在复用情况,这时的ThreadLocal 的使用要谨慎使用。

web请求下 的ThreadLocal  使用要保证:请求进来的时候set,请求回去的时候remove。只有这样才能保证请求内的ThreadLocal  是唯一的。 这个特性在深刻的提醒我们:一次http请求和tomcat启动处理业务的线程并非一一对应的,而是通过一个线程池进行调度。 
错误的使用案例:

  1. @Controller
  2. public class ThreadLocalController {
  3. private static final ThreadLocal<Integer> id = new ThreadLocal<Integer>();
  4. @ResponseBody
  5. @RequestMapping("/threadLocalTest")
  6. public Map<String, Object> threadLocalTest() {
  7. Integer myId = id.get();
  8. if (myId == null) {
  9. id.set(1);
  10. } else {
  11. id.set(id.get() + 1);
  12. }
  13. System.out.println(id.get());
  14. Map<String, Object> retMap = new LinkedHashMap<String, Object>();
  15. retMap.put("id", id.get());
  16. return retMap;
  17. }
  18. }

以上代码运行的时候会发现,命令行打印的id 是不确定的,这时因为tomcat本身对请求做线程池缓存业务处理线程导致的。

正确的使用案例:

  1. @Controller
  2. public class ThreadLocalController {
  3. private static final ThreadLocal<Integer> id = new ThreadLocal<Integer>();
  4. @ResponseBody
  5. @RequestMapping("/threadLocalTest")
  6. public Map<String, Object> threadLocalTest() {
  7. Integer myId = id.get();
  8. if (myId == null) {
  9. id.set(1);
  10. } else {
  11. id.set(id.get() + 1);
  12. }
  13. System.out.println(id.get());
  14. Map<String, Object> retMap = new LinkedHashMap<String, Object>();
  15. retMap.put("id", id.get());
  16. id.remove();
  17. return retMap;
  18. }
  19. }

以上代码每次输出的都是1,注意id.remove() 方法的调用,在每次请求结束的时候remove对象。

更多的情况下,做为系统级别的,可以在filter下做ThreadLocal对象set 和 remove 操作!

ThreadLocal 在web环境下使用的边界问题的更多相关文章

  1. Spring-IOC 在非 web 环境下优雅关闭容器

    当我们设计一个程序时,依赖了Spring容器,然而并不需要spring的web环境时(Spring web环境已经提供了优雅关闭),即程序启动只需要启动Spring ApplicationContex ...

  2. Shiro在Web环境下集成Spring的大致工作流程

    1,Shiro提供了对Web环境的支持,其通过一个 ShiroFilter 入口来拦截需要安全控制的URL,然后进行相应的控制.      ①配置的 ShiroFilter 实现类为:org.spri ...

  3. windows环境vagrant修改静态资源文件,centos虚拟机中nginx的web环境下不生效

    最近上手krpano,本地修改了krpano.html文件或者xml文件,在虚拟机环境打开文件是修改过来了,在nginx中就是不生效. 修改nginx.conf中http{}中的 sendfile  ...

  4. Asp.Net在多线程环境下的状态存储问题

    在应用开发中,我们经常需要设置一些上下文(Context)信息,这些上下文信息一般基于当前的会话(Session),比如当前登录用户的个人信息:或者基于当前方法调用栈,比如在同一个调用中涉及的多个层次 ...

  5. Shiro集成web环境[Springboot]-认证与授权

    Shiro集成web环境[Springboot]--认证与授权 在登录页面提交登陆数据后,发起请求也被ShiroFilter拦截,状态码为302 <form action="${pag ...

  6. Shiro集成web环境[Springboot]-基础使用

    Shiro集成web环境[Springboot] 1.shiro官网查找依赖的jar,其中shiro-ehcache做授权缓存时使用,另外还需要导入ehcache的jar包 <dependenc ...

  7. PHP 命令行模式实战之cli+mysql 模拟队列批量发送邮件(在Linux环境下PHP 异步执行脚本发送事件通知消息实际案例)

    源码地址:https://github.com/Tinywan/PHP_Experience 测试环境配置: 环境:Windows 7系统 .PHP7.0.Apache服务器 PHP框架:ThinkP ...

  8. SpringSecurity环境下配置CORS跨站资源共享规则

    一.CORS简述 要说明CORS(Cross Origin Resourse-Sharing) 跨站资源共享,就必须先说同源策略.长话短说,同源策略就是向服务端发起请求的时候,以下三项必须与当前浏览器 ...

  9. Docker容器环境下ASP.NET Core Web API应用程序的调试

    本文主要介绍通过Visual Studio 2015 Tools for Docker – Preview插件,在Docker容器环境下,对ASP.NET Core Web API应用程序进行调试.在 ...

随机推荐

  1. Conquering Keokradong && Get the Containers(二分)

    Conquering Keokradong Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu ...

  2. C# 热水器

    需求分析:现在有一个烧水器假设水温升高到100度为开水请用设计程序模拟整个烧水的过程,打开热水器,当水温达到95度时报警器开始发出警报,水温达到100度时,断开热水器电源. 我们使用常规的思维去分析这 ...

  3. Starting httpd:Could not reliably determine the server's fully qualified domain name

    #service httpd start #Starting httpd: httpd: Could not reliably determine the server's fully qualifi ...

  4. Oracle Linux Server 7安装VMwareTools问题

    OracleLinuxServer7安装VMwareTools问题#./vmware-install.pl时报错:#-bash: ./vmware-instal.pl:/usr/bin/perl:ba ...

  5. Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent

    修改pom.xml文件,添加以下属性 <project> ... <properties> <project.build.sourceEncoding>UTF-8& ...

  6. C# 调用存储过程传入表变量作为参数

    首先在SQLServer定义一个自定义表类型: USE [ABC] GO CREATE TYPE [ABC].[MyCustomType] AS TABLE( ) NOT NULL, ) NULL, ...

  7. 用自动化运维工具解放IT运维

    何谓自动化运维,即在最少的人工干预下,结合运用脚本与第三方工具,保证业务系统7*24小时高效稳定运行.这应该是所有业务系统运维终极目标. 我们对运维的要求通常是: 1.事前预警 在故障出现之前,管理人 ...

  8. foreach的用法(转)

    JDK1.5加入的增强for和循环. foreach语句使用总结增强for(part1:part2){part3}; part2中是一个数组对象,或者是带有泛性的集合. part1定义了一个局部变量, ...

  9. java 短信发送例子 tdy

    import java.io.IOException; import java.util.logging.Level;import java.util.logging.Logger;import or ...

  10. 【ecos学习3】redboot on vmware 网络配置

    需要图形化编译的时候必须 Build->Packages 加入:Common ethernet support 才可以有网络功能 导入vmare需要修改网络连接模式: 1- 设置redbootI ...