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. jmeter断言接口响应字段大小

    一,有时候断言需要判断接口返回某个字段值是否大于或者小于预期值,此时断言需要用到BeanShell断言 写法如下: import com.alibaba.fastjson.JSONObject; // ...

  2. minikube windows hyperx填坑记

    minikube windows hyperx填坑记 安装了一天半,还是没行,先放弃 开始 minikube start --vm-driver=hyperv --hyperv-virtual-swi ...

  3. U盘安装Windows原版系统(安装方式有很多,我讲我的安装方式)

    我陈某人,也是安装过至少200部台式或笔记本的人物. 低调,低调,开个玩笑~ 安装方式有很多,我讲我的安装方式,欢迎收藏. 1.下载准备文件下载.iso原版系统镜像文件http://msdn.itel ...

  4. 关于11G DataGuard 日志传输的案例

    案例探讨 在归档和非归档模式下,配置参数log_archive_dest_2后,DG的备库是否传输日志. 案例环境描述 本次环境如下,一套RAC+单机DG,然后从DG还原出来一个单独的测试库A,测试库 ...

  5. Linux之文件权限

    在Linux系统中,root用户基本对于每个文件都有可操作性,但是普通用户可能只能查看特定的文件,这是因为文件存在的权限机制,初步掌握文件的基本权限就操作可以对一些系统文件或者自定义文件有一个操作空间 ...

  6. VMware卸载有残留,再安装时报错提示MSI Failed

    引用自吾爱破解论坛:https://www.52pojie.cn/thread-455779-1-1.html 解决方法:软件自动清理法: 软件 地址:下载地址1:链接:http://pan.baid ...

  7. 安装linux虚拟机

    虚拟机安装流程 1. 安装系统 安装完成 2. 安装VMware tools linux(ubuntu 18.04 Desktop) 手动安装 1) 加载光驱 2) 双击进入光驱,在光驱的目录下,打开 ...

  8. 手把手教你使用 Clion 开发 Linux C++ 项目

    手把手教你使用 Clion 开发 Linux C++ 项目 关于CLion CLion是一款专为开发C及C++所设计的跨平台IDE.它是以IntelliJ为基础设计的,包含了许多智能功能来提高开发人员 ...

  9. 使用Spring的@Async创建异步方法

    使用Spring的@Async创建异步方法 在开发系统的过程中,通常会考虑到系统的性能问题,提升系统性能的一个重要思想就是“串行”改“并行”.说起“并行”自然离不开“异步”,今天我们就来聊聊如何使用S ...

  10. Running ROS on Windows 10

    1.在Windows10下安装ROS.需要开启WSL.参考 2.修改ubuntu国内源,可以提高安装包下载更新速度. (1)原文件备份:sudo cp /etc/apt/sources.list /e ...