zoukankan      html  css  js  c++  java
  • SpringMVC:单例与并发问题

    Spring中的Bean默认都是单例(singleton),Spring中Bean的scope属性有五种类型:

    1. singleton 表示在spring容器中的单例,通过spring容器获得该bean时总是返回唯一的实例
    2. prototype 表示每次获得bean都会生成以新的对象
    3. request 表示在一次Htttp请求内有效(只适用于web应用)
    4. session 表示在一个用户会话内有效(只适用于web应用)
    5. globalSession 表示在全局会话内有效(只适用于web应用)

    SpringMVC中Controller类默认Scope是单例,因而在Controller类中使用成员变量时需要注意并发的问题,举例说明:

    @Controller
    public class ExampleAction {
    private int singletonInt=0;
    @RequestMapping(value
    = "/test") @ResponseBody public String singleton(HttpServletRequest request, HttpServletResponse response) throws Exception { String data=request.getParameter("data"); if(data!=null&&data.length()>0){ try{ int paramInt= Integer.parseInt(data); singletonInt = singletonInt + paramInt; } catch(Exception ex){ singletonInt+=10; } }else{ singletonInt+=1000; } return String.valueOf(singletonInt); } }

    请求三次  http://localhost:8080/test?data=15 ,得到的结果分别是15 30 45,由此说明Controller是单例

    单例的好处也很明显:不用每次创建Controller,减少了对象创建和垃圾收集的时间。

    当有多个用户同时请求一个服务时,容器会给每一个请求分配一个线程,各个线程是不会相互影响,举例如下:

    @RequestMapping(value = "/sleepdata")
    @ResponseBody
    public String switcher(HttpServletRequest request, HttpServletResponse response) throws Exception {
      String sleep = request.getParameter("sleep");
      if (sleep.equals("on")) {
          Thread.currentThread().sleep(100000);
           return "sleep on";
       } else {
           return sleep;
      }
    }

    分别发送两个请求,

    第一个请求:http://localhost:8080/sleepdata?sleep=on

    第二个请求:http://localhost:8080/sleepdata?sleep=test

    验证结果:第一个请求发出去以后,本地服务器等待100s,然后返回结果”sleep on”,在本地服务器等待的者100s当中,发送第二个请求,直接返回结果”test”。说明之间的线程是不互相影响的

    单例的状态改变:体现为该单例的成员属性值的修改

    有状态对象(Stateful Bean):就是有成员变量的对象,可以保存数据,是非线程安全的

    无状态对象(Stateless Bean):就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的

    Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态

    浏览器访问服务器时将会产生一个session,同时会产生多个线程来处理请求,代码示例如下:

    @Controller
    public class SlemController {
    
        @GetMapping("/slem")
        public ResponseEntity<?> slem(HttpServletRequest request) {
    
            return ResponseEntity.ok("SESSIONID " + request.getSession().getId() + " THREAD " + Thread.currentThread().getName());
        }
    }

    分别用Chrome和Firefox访问这个controller,可以得到如下结果:同一个浏览器sessionid都是相同,但是thread不同,由此可以验证SpringMVC的多线程,测试发现,一个session最多创建10个线程,有待查验。

     内容来源网络,非原创,侵删

  • 相关阅读:
    死锁篇
    java线程池
    sql server 多行数据指定字符串拼接
    动态提交 表格
    ABP
    DDD学习
    sql 语句插入数据返回id
    Post方式提交,通过上下文HttpContext,Request[""]获取
    JQ的过滤隐藏
    sql 查询有多少行
  • 原文地址:https://www.cnblogs.com/colin220/p/9623701.html
Copyright © 2011-2022 走看看