1.SpringMVC默认是单例的,使用成员变量在并发状态下该成员变量的值是被共享的

测试平台   我们目前正在开发的电商项目  (架构组成SpringCloud + SpringBoot + Spring + SpringMVC + Mybatis)

测试说明  构造两个并发访问的请求,它们都会使用一个成员变量,其中一个请求会执行一段耗时15秒左右的for循环的代码,另外一个请求不会执行这段代码,但会修改成员变量的值

测试过程  第一个请求先访问,在执行for循环时紧接着第二个请求访问,第二个请求会马上执行完并且改变成员变量的值,最后看前面这个请求执行完15秒的for循环后再使用这个成员变量时,值有没有改变

测试源码  

    

@RestController
@RequestMapping("/service")
public class SurvivalGoldReceiveController extends BaseController { private String nowDate = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss").format(new Date()); @RequestMapping(value = "/toSurvivalGoldReceive")
public ModelAndView toSurvivalGoldReceive(){
HttpServletRequest request = this.getRequest();
GeCustomer geCustomer = (GeCustomer)request.getSession().getAttribute(UserPersonalConstant.LOGIN_USER);
logger.info("start--nowDate = " + geCustomer.getCustomeraccount() + nowDate);
logger.info("其它请求进来后");
if ("youyuqi02".equals(geCustomer.getCustomeraccount())) {
StringBuilder sb = new StringBuilder();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
sb.append("测试SpringMVC中使用成员变量" + i);
sb.append("测试SpringMVC中使用成员变量" + i);
sb.append("测试SpringMVC中使用成员变量" + i);
sb.append("测试SpringMVC中使用成员变量" + i);
sb.append("测试SpringMVC中使用成员变量" + i);
sb.delete(0,sb.length());
}
long estimatedTime = System.currentTimeMillis() - startTime;
logger.info("执行一亿次字符串的拼接与删除耗时 : " + String.valueOf(estimatedTime).substring(0,2) + "秒"); //1s=1000毫秒=1000000微秒=1000000000纳秒
}else{
nowDate = "成员变量被其它请求改变了";
}
logger.info("end--nowDate = " + geCustomer.getCustomeraccount() + nowDate);
if(geCustomer == null){
return go("/vipcenter/home");
}else{
return go("/vipcenter/survivalGoldReceive/survivalGoldReceiveList");
}
}
}

测试结果:第二个请求将成员变量nowDate的值改为了字符串“成员变量被其它请求改变了”,第一个请求再使用这个成员变量时,值已经发生了改变

总结:SpringMVC在单例情况下发生并发时会修改成员变量的值,所以慎用成员变量

2.设置controller为多例,@Scope("prototype")

测试源码

@RestController
@Scope("prototype")
@RequestMapping("/service")
public class SurvivalGoldReceiveController extends BaseController { private String nowDate = new SimpleDateFormat("yyyy-MM-dd HH:MM:ss").format(new Date()); @RequestMapping(value = "/toSurvivalGoldReceive")
public ModelAndView toSurvivalGoldReceive(){
HttpServletRequest request = this.getRequest();
GeCustomer geCustomer = (GeCustomer)request.getSession().getAttribute(UserPersonalConstant.LOGIN_USER);
logger.info("start--nowDate = " + geCustomer.getCustomeraccount() + nowDate);
logger.info("其它请求进来后");
if ("youyuqi02".equals(geCustomer.getCustomeraccount())) {
StringBuilder sb = new StringBuilder();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
sb.append("测试SpringMVC中使用成员变量" + i);
sb.append("测试SpringMVC中使用成员变量" + i);
sb.append("测试SpringMVC中使用成员变量" + i);
sb.append("测试SpringMVC中使用成员变量" + i);
sb.append("测试SpringMVC中使用成员变量" + i);
sb.delete(0,sb.length());
}
long estimatedTime = System.currentTimeMillis() - startTime;
logger.info("执行一亿次字符串的拼接与删除耗时 : " + String.valueOf(estimatedTime).substring(0,2) + "秒"); //1s=1000毫秒=1000000微秒=1000000000纳秒
}else{
nowDate = "成员变量被其它请求改变了";
}
logger.info("end--nowDate = " + geCustomer.getCustomeraccount() + nowDate);
if(geCustomer==null){
return go("/vipcenter/home");
}else{
return go("/vipcenter/survivalGoldReceive/survivalGoldReceiveList");
}
}
}

测试结果  第一个请求最后获取的成员变量的值并未改变

总结 第二种是多例的,每次访问会创建一个Controller对象,属于线程安全的,但会过多的耗费内存,第一种是单例的,只会创建一次对象,在并发情况下会修改成员变量的值,但会节省内存空间,所以,老司机都用第一种,但会有意识的避免使用成员变量。

参考文献 springMVC 谨慎使用成员变量https://blog.csdn.net/panda_in5/article/details/78528762

SpringMVC成员变量并发状态下使用测试的更多相关文章

  1. php高并发状态下文件的读写

    php高并发状态下文件的读写   背景 1.对于PV不高或者说并发数不是很大的应用,不用考虑这些,一般的文件操作方法完全没有问题 2.如果并发高,在我们对文件进行读写操作时,很有可能多个进程对进一文件 ...

  2. 读/写锁的实现和应用(高并发状态下的map实现)

    程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源.但是如果有一个线程想去写这些共享资 ...

  3. binlog在并发状态下的记录

    前两天看binlog发现个奇怪的地方:对于position靠后的记录,timestamp却比之前的记录还要小.当时觉得大概和并发有关系 后来做了个实验 开两个session 对于session1: b ...

  4. C语言中 struct成员变量顺序对内存的占用

    在C语言的结构体中,是会按照其变量类型来进行分配内存大小的.但是对于不同的编译器,结果是不同的,在VC++6.0中是怎么个分配情况呢?用一下C中的关键字sizeof()来测试下,注意sizeof()不 ...

  5. java在继承中父类的成员变量是否会被子类所覆盖

    假如 父类 int num =7:子类 int num =9:父类是否会被子类所覆盖? 给你看两个例子: 第一个例子: 第二个例子: 这两个例子的区别只有一句话   由此证明了子类从父类继承的时候   ...

  6. 访问权限系列一(public/private/protected/default):成员变量

    通过两个程序包对自身或互相之间的访问,得到结果.(先编译Test_01,得到class文件,通过Test的集中访问情况) 如下Test.java中内容: package com.java; /* * ...

  7. python中的类的成员变量以及property函数

    1 python类的各种变量 1.1 全局变量 在类外定义的变量. 1.2 类变量 定义在类里面,所有的函数外面的变量.这个变量只有一份,是所有的对象共有的.在类外用“类.”来引用. 1.3 实例变量 ...

  8. C++成员变量内存对齐问题,ndk下非对齐的内存访问导致BUS_ADRALN

    同样的代码,在vs下运行正常,在android ndk下却崩溃: signal 7(SIGBUS),code 1 (BUS_ADRALN),fault addr 0xe6b82793 Func(sho ...

  9. SpringMVC处理Date类型的成员变量方法

    原文链接:http://www.tuicool.com/articles/aYfaqa 在使用 SpringMVC 的时候,我们可能需要将一个对象从 View 传递给 Controller .而当这个 ...

随机推荐

  1. pc端 页面 显示在手机 一行控制适配问题

    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">

  2. matlab工作空间数据导入simulink

    使用的是其中一种方式: 第一步在工作命令区  ,写命令: 第二步:保证导入simulink区,及from worker设置:  其中注意设置你的采样时间, 第三步设置scop  : 采样时承接数据线上 ...

  3. python练习题-day26

    #bim(property) class People: def __init__(self,name,weight,height): self.name=name self.weight=weigh ...

  4. JavaScript实现预览本地上传图片

    <html> <head> <title> www.jb51.net图片上传预览 </title> <script> function Pr ...

  5. 《图解HTTP》读书笔记(七:通信数据转发程序-代理/网关/隧道)

    HTTP通信时,除客户端和服务器以外,还有一些用于通信数据转发的应用程序,例如代理.网关和隧道,它们可以配合服务器工作.这些服务器和应用程序可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服 ...

  6. spring-boot logback配置

    接着上篇的代码,日志在不同环境下的配置也不一样,所以要分开配置,主要使用maven的profile 1.1 在pom.xml中添加 <profiles> <profile> & ...

  7. 2019-04-20 Python之科学计算库学习总结

    一.numpy库和matplotlib库的学习 (1)numpy库介绍:科学计算包,支持N维数组运算.处理大型矩阵.成熟的广播函数库.矢量运算.线性代数.傅里叶变换.随机数生成,并可与C++/Fort ...

  8. 极客时间 深入拆解java虚拟机 一至三讲学习总结

    为什么要学习java虚拟机 1.学习java虚拟机的本质,是了解java程序是如何被执行且优化的.这样一来,才可以从内部入手,达到高效编程的目的.与此同时,你也可以为学习更深层级.更为核心的java技 ...

  9. python3.6安装docx模块

    1.下载 python_docx-0.8.6-py2.py3-none-any.whl 地址: http://www.lfd.uci.edu/~gohlke/pythonlibs/2.在这个网页的最下 ...

  10. Docker:从头开始基于CentOS-Minimal安装Docker

    基础环境:win10+vmware 14 一.CentOS-Minimal安装 虚拟机安装CentOS-Minimal的步骤不多说,网络选Net,硬件不需要的什么声卡打印机全都删掉没什么问题,然后ce ...