SpringMVC成员变量并发状态下使用测试
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成员变量并发状态下使用测试的更多相关文章
- php高并发状态下文件的读写
php高并发状态下文件的读写 背景 1.对于PV不高或者说并发数不是很大的应用,不用考虑这些,一般的文件操作方法完全没有问题 2.如果并发高,在我们对文件进行读写操作时,很有可能多个进程对进一文件 ...
- 读/写锁的实现和应用(高并发状态下的map实现)
程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源.但是如果有一个线程想去写这些共享资 ...
- binlog在并发状态下的记录
前两天看binlog发现个奇怪的地方:对于position靠后的记录,timestamp却比之前的记录还要小.当时觉得大概和并发有关系 后来做了个实验 开两个session 对于session1: b ...
- C语言中 struct成员变量顺序对内存的占用
在C语言的结构体中,是会按照其变量类型来进行分配内存大小的.但是对于不同的编译器,结果是不同的,在VC++6.0中是怎么个分配情况呢?用一下C中的关键字sizeof()来测试下,注意sizeof()不 ...
- java在继承中父类的成员变量是否会被子类所覆盖
假如 父类 int num =7:子类 int num =9:父类是否会被子类所覆盖? 给你看两个例子: 第一个例子: 第二个例子: 这两个例子的区别只有一句话 由此证明了子类从父类继承的时候 ...
- 访问权限系列一(public/private/protected/default):成员变量
通过两个程序包对自身或互相之间的访问,得到结果.(先编译Test_01,得到class文件,通过Test的集中访问情况) 如下Test.java中内容: package com.java; /* * ...
- python中的类的成员变量以及property函数
1 python类的各种变量 1.1 全局变量 在类外定义的变量. 1.2 类变量 定义在类里面,所有的函数外面的变量.这个变量只有一份,是所有的对象共有的.在类外用“类.”来引用. 1.3 实例变量 ...
- C++成员变量内存对齐问题,ndk下非对齐的内存访问导致BUS_ADRALN
同样的代码,在vs下运行正常,在android ndk下却崩溃: signal 7(SIGBUS),code 1 (BUS_ADRALN),fault addr 0xe6b82793 Func(sho ...
- SpringMVC处理Date类型的成员变量方法
原文链接:http://www.tuicool.com/articles/aYfaqa 在使用 SpringMVC 的时候,我们可能需要将一个对象从 View 传递给 Controller .而当这个 ...
随机推荐
- Libvmi实现分析
LibVMI是一个专注于读写虚拟机内存的自省库,它能够监视虚拟机底层的运行细节并将其还原.LibVMI支持对Xen及KVM虚拟化平台上的运行虚拟机进行自省操作,针对KVM虚拟化平台,LibVMI对QE ...
- numpy(五)
排序: x=np.array([2,5,6,2,3,5]) np.sort(x) 不改变原数组 x.sort() 改变原数组 i=np.argsort(x) 返回排序好的索引值 x[i] 使用花哨索 ...
- mysql--实现oracle的row_number() over功能
有时候我们想要得到每个分组的前几条记录,这个时候oracle中row_number函数使用非常方便,但可惜mysql没有.网上搜了些实现方法. 表flow_task有phaseno(序列号),obje ...
- win10配置java环境变量,解决javac不是内部或外部命令等问题
win10配置java环境变量,解决javac不是内部或外部命令等问题 https://www.cnblogs.com/qianji/p/6402690.html
- 运维面试题之k8s
前言: 到了如今年k8s已经是事实上的容器集群标准了,是时候展现我真正的祖传k8s实力了 吐槽: 我干嘛要知道这些,能用不就行了k8s真香 Kubernetes有哪些特性? Kubernetes是自动 ...
- pwn学习日记Day1 基础知识积累
ida / od 窗口(针对od操作) 反汇编窗口:显示被调试程序的反汇编代码,标题栏上的地址.HEX 数据.反汇编.注释可以通过在窗口中右击出现的菜单 界面选项->隐藏标题 或 显示标题 来进 ...
- patA1059 Prime Factors
这个问题叫做质因子分解,花了大概两个小时写对了.这道题细节挺多的,书上提到了几点,一个是n=1的话需要特判.有一个很容易错的点就是n一开始要先用一个变量保存起来,不保存的话后面有点麻烦,所以建议还是先 ...
- C语言中格式字符串
C语言中格式字符串的一般形式为: %[标志][输出最小宽度][.精度][长度]类型, 其中方括号[]中的项为可选项. 一.类型 我们用一定的字符用以表示输出数据的类型,其格式符和意义下表所示: 字符 ...
- EF:分页查询 + 条件查询 + 排序
/// <summary> /// linq扩展类---zxh /// </summary> /// <typeparam name="T">& ...
- windows server 2008 R2服务器无法通过ShellClass获取mp3音乐时长
我们先看一段代码,获取mp3播放时长: #region GetMediaDetailInfo 获取媒体文件属性信息 /// <summary> /// 获取媒体文件属性信息 /// < ...