Spring controller、service的单例模式

spring 中的单例模式在并发的情况下是怎么保证数据不会混乱的??
首先我们知道Spring 中controller、service、dao都为单例模式(注:默认状态)。

既然是单例,那么在并发的情况下,会发生什么?

废话不多说,看代码。

后台:

@Controller
@RequestMapping("/user")
public class UserController {
 
    @Autowired
    private UserServiceI userService;
    
    private int i;
    
    @POST
    @RequestMapping("test.do")
    @ResponseBody
    public Result test(User user) {
        System.out.println(user.getUserName()+":进入方法");
        i++;
        System.out.println("开始阻塞");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("阻塞结束");
        System.out.println("i="+i);
        System.out.println("此时UserName:"+user.getUserName());
        return null;
    }
}
前台:
<div>
        <fieldset>
            <form action="<%=basePath%>user/test.do" method="post">
                <input name="userName"><br> 
                                <input type="submit" value="提交">
            </form>
        </fieldset>
</div>
两台电脑:一个输入1,一个输入2,点击提交,提交时间间隔1秒左右即可。
控制台输出:

1:进入方法
开始阻塞
2:进入方法
开始阻塞
阻塞结束
i=2
此时UserName:1
阻塞结束
i=2
此时UserName:2
看到,成员变量 i 受到了并发的影响,而我们表单提交的userName参数,并未收到并发的影响。

再测,继续提交表单,看到 i 的值一直在自增,对于我来说这是一个吓人的发现,作了这么久的程序员,刚发现这个问题。。。多久就不透露了,丢人。。

下面是来自博客的答案:

成员方法也是共享的,为什么就不会出现问题呢?
==================================================
java 里,每个线程都有自己独享的空间,也就是栈内存。线程在调用方法的时候,会创建一个栈帧。也就是说调用一个方法的时候,也就是一个栈帧的入栈过程,该方法执行完毕,栈帧也就出栈了。
换句话讲,成员方法对于每个线程事实上是私有的,而不是你表面看上去的那样是 "共享" 的。

那么为什么成员变量会出问题呢?
==================================================
如你所知道的,每个新建对象都存放在堆中,每个持有该对象引用的线程,都可以访问到它(只要你有那个权限)。
这也就是说,成员变量对于每个线程,事实上是共享的。

而service层呢?dao呢?

经过测试,与controller结论相同。

转载地址:https://blog.csdn.net/zhangweijie_cn/article/details/70212630 
 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值