Spring MVC 线程安全问题的思考

在读一些博文的时候发现有些文章对SpringMVC的Controller线程安全的验证并不正确,比如没有探究controller线程不安全的具体原因,比如将请求线程当做controller多例的证明,以下将验证。
http://bbs.csdn.net/topics/390894585
http://bbs.csdn.net/topics/390891861#post-398241838

1.request请求线程与controllte的关系是什么?

简易的验证方法代码

在网上随便下载了一个压力测试工具

测试结果如下

从打印的日志可以看出,请求时多线程请求的,但是每次请求过来调用的Controller对象都是一个,而不是一个请求过来就创建一个controller对象

那为什么说controller是不安全的呢?

原因就在于如果这个controller对象是单例的,那么如果不小心在类中定义了类变量,那么这个类变量是被所有请求共享的,这可能会造成多个请求修改该变量的值,出现与预期结果不符合的异常。

接下来将验证多并发的情况下controller的线程不安全的具体表现、通过配置实现controller多例

在单例的情况下 相当于所有类变量对于每次请求都是共享的,每一次请求对类变量的修改都是有效的

  1. private static int st=0;
  2. private int index=0;
  3. @RequestMapping(value="/testcontrollersinglon",method=RequestMethod.GET)
  4. @ResponseBody
  5. public String testControllerSinglon(HttpServletRequest request){
  6. try {
  7. System.out.println(st++ + " | " + index++);
  8. return "yes";
  9. } catch (Exception e) {
  10. e.printStackTrace();
  11. return "error";
  12. }
  13. }

看一下打印的日志

通过日志可以看出 变量index为所有请求共享

那有没有办法让controller不以单例而以每次请求都重新创建的形式存在呢?

答案是当然可以,只需要在类上添加注解@Scope("prototype")即可,这样每次请求调用的类都是重新生成的(每次生成会影响效率)

添加@Scope("prototype")后我们再看看日志就会看出区别了

虽然这样可以解决问题,但增加了时间成本,总让人不爽,还有其他方法么?答案是肯定的!使用ThreadLocal 来保存类变量,将类变量保存在线程的变量域中,让不同的请求隔离开来

Spring MVC 线程安全问题的思考的更多相关文章

  1. 总结: Struts2 + Spring 的线程安全问题

    1. 首先Struts2 本身是安全的 其原理大概是:Strtus2会获取到用户的http请求,然后负责给每个请求实例化一个Action 对象,但是大家注意,这里的action对象和Struts1里面 ...

  2. Spring中构造器、init-method、@PostConstruct、afterPropertiesSet孰先孰后,自动注入发生时间以及单例多例的区别、SSH线程安全问题

    首先明白,spring的IOC功能需要是利用反射原理,反射获取类的无参构造方法创建对象,如果一个类没有无参的构造方法spring是不会创建对象的.在这里需要提醒一下,如果我们在class中没有显示的声 ...

  3. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  4. spring mvc web应用启动时就执行特定处理(线程启动)

    package com.sdt.platform.index.controller; import java.net.URL; import java.util.List; import java.u ...

  5. spring + spring mvc + tomcat 面试题(史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

  6. springmvc中request的线程安全问题

    SpringMvc学习心得(四)springmvc中request的线程安全问题 标签: springspring mvc框架线程安全 2016-03-19 11:25 611人阅读 评论(1) 收藏 ...

  7. spring mvc 的Controller类默认Scope是单例(singleton)的

    使用Spring MVC有一段时间了,之前一直使用Struts2,在struts2中action都是原型(prototype)的, 说是因为线程安全问题,对于Spring MVC中bean默认都是(s ...

  8. Servlet, Struts2和SpringMVC 并发访问线程安全问题

    第一部分: Servlet不是线程安全的. 要解释Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP ...

  9. Spring MVC知识

    f-sm-1. 讲下SpringMvc和Struts1,Struts2的比较的优势 性能上Struts1>SpringMvc>Struts2 开发速度上SpringMvc和Struts2差 ...

随机推荐

  1. XML真正强大的功能是来自其元素与封装的内容

    创建文档类型声明 一般而言,XML声明放在文档顶部.在PHP中声明十分简单:只需实例化一个DOM文档类的对象并赋予它一个版本号.查看程序清单A: 程序清单 A <?php// create do ...

  2. HDU 2222 Keywords Search(AC自动机模版题)

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  3. 奥迪--S5

    --型号:S5 --生产:奥迪进口 --价格:60-80W --发动机:3T 333马力 V6,机械增压 --变速箱:7档双离合 --气缸排列:V --总部:德国,英戈尔施塔特 --类型:中型车 -- ...

  4. Linux内核设计第一周 ——从汇编语言出发理解计算机工作原理

    Linux内核设计第一周 ——从汇编语言出发理解计算机工作原理 作者:宋宸宁(20135315) 一.实验过程 图1 编写songchenning5315.c文件 图2 将c文件汇编成32位机器语言 ...

  5. linux查看ssh用户登录日志与操作日志

    linux查看ssh用户登录日志与操作日志 2013-11-01转载   ssh用户登录日志 linux下登录日志在下面的目录里:  代码如下 复制代码 cd /var/log 查看ssh用户的登录日 ...

  6. RDIFramework.NET ━ 9.6 模块(菜单)管理 ━ Web部分

    RDIFramework.NET ━ .NET快速信息化系统开发框架 9.6  模块(菜单)管理 -Web部分  模块(菜单)管理是整个框架的核心,主要面向系统管理人员与开发人员,对普通用户建议不要授 ...

  7. Leetcode: K-th Smallest in Lexicographical Order

    Given integers n and k, find the lexicographically k-th smallest integer in the range from 1 to n. N ...

  8. JDBC-java访问数据库

    定义:JDBC是一个独立于数据库管理系统的,通用的SQL数据库存取和操作的公共接口 (由JAVA类和接口组成,接口由各数据库厂家负责实现) 使用方法: 1.加载驱动 Class.forName(&qu ...

  9. Eclipse中为自己写完的函数添加注释(快捷键ALT+SHIFT+J)

    函数名上右键:Source--->Generate Element Comment

  10. jquery隐藏table表格的某一列

    jquery隐藏table表格的某一列: $('table tr').find('td:eq(13)').hide(); 隐藏table的第13列