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. decode 函数将字符串从某种编码转为 unicode 字符

    环境:Ubuntu, Python 2.7 基础知识 这个程序涉及到的知识点有几个,在这里列出来,不详细讲,有疑问的直接百度会有一堆的. 1.urllib2 模块的 request 对像来设置 HTT ...

  2. Android课程---课下练习(表格、线性和相对布局)

    1.表格布局 练习代码: <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns: ...

  3. BZOJ4448:[SCO2015]情报传递

    题目大意:给你一棵树,有两种操作,一个是修改某个点的权值,另一个是询问两点之间的距离以及路径上小于某个值的数的个数. 询问两点之间距离直接lca即可,对于求个数的问题可以用主席树完成. #includ ...

  4. PHP 上传大文件

  5. DS Tree 已知先序、中序 => 建树 => 求后序

    参考:二叉树--前序和中序得到后序 思路历程: 在最初敲的时候,经常会弄混preorder和midorder的元素位置.大体的思路就是在preorder中找到根节点(根节点在序列的左边),然后在mid ...

  6. HDFS的概念

    1.数据块 每个磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位.构建于单个磁盘之上的文件系统通过磁盘块来管理该文件系统中的块,该文件系统块的大小可以是磁盘块的整数倍.文件系统快一半为几千字 ...

  7. CSS 伪元素&伪类

    单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪元素 伪元素 属性 描述 CSS :first-letter 向文本的第一个字母添加特殊样式 1 :first-line 向文本的首行添加特殊 ...

  8. swt小知识点

    1 换java小图标 Image image=this.getToolkit().getImage("d:/pu1.jpg"); setIconImage(image); 2 去掉 ...

  9. sql操作之修改记录值

    mysql修改.删除数据记录 用update修改记录 UPDATE tbl_name SET 要更改的列 WHERE 要更新的记录 这里的 WHERE 子句是可选的,因此如果不指定的话,表中的每个记录 ...

  10. soap ui 进行接口测试

    [前置条件] 1. 电脑上已安装soap UI 5.0 2. 电脑上已安装eclipse. JDK1.6.tomcat 3. eclipse已经成功的配置JDK1.6.tomcat [操作步骤] 1. ...