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 
 

猜你喜欢

转载自blog.csdn.net/fu_zhongyuan/article/details/88823122