zoukankan      html  css  js  c++  java
  • Spring MVC 线程安全问题的思考

    Spring MVC 线程安全问题的思考

    在读一些博文的时候发现有些文章对SpringMVC的Controller线程安全的验证并不正确,比如没有探究controller线程不安全的具体原因,比如将请求线程当做controller多例的证明,以下将验证。
    http://bbs.csdn.net/topics/390894585
    http://bbs.csdn.net/topics/390891861#post-398241838
    

    1.request请求线程与controllte的关系是什么?

    简易的验证方法代码

    在网上随便下载了一个压力测试工具

    测试结果如下

    从打印的日志可以看出,请求时多线程请求的,但是每次请求过来调用的Controller对象都是一个,而不是一个请求过来就创建一个controller对象

    那为什么说controller是不安全的呢?

    原因就在于如果这个controller对象是单例的,那么如果不小心在类中定义了类变量,那么这个类变量是被所有请求共享的,这可能会造成多个请求修改该变量的值,出现与预期结果不符合的异常。

    接下来将验证多并发的情况下controller的线程不安全的具体表现、通过配置实现controller多例

    在单例的情况下 相当于所有类变量对于每次请求都是共享的,每一次请求对类变量的修改都是有效的

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. private static int st=0;  
    2. private int index=0;  
    3. @RequestMapping(value="/testcontrollersinglon",method=RequestMethod.GET)  
    4.     @ResponseBody  
    5.     public String testControllerSinglon(HttpServletRequest request){  
    6.         try {  
    7.             System.out.println(st++ + " | " + index++);  
    8.             return "yes";  
    9.         } catch (Exception e) {  
    10.             e.printStackTrace();  
    11.             return "error";  
    12.         }  
    13.     }  

    看一下打印的日志


    通过日志可以看出 变量index为所有请求共享 

    那有没有办法让controller不以单例而以每次请求都重新创建的形式存在呢?

    答案是当然可以,只需要在类上添加注解@Scope("prototype")即可,这样每次请求调用的类都是重新生成的(每次生成会影响效率)

    添加@Scope("prototype")后我们再看看日志就会看出区别了

    虽然这样可以解决问题,但增加了时间成本,总让人不爽,还有其他方法么?答案是肯定的!使用ThreadLocal 来保存类变量,将类变量保存在线程的变量域中,让不同的请求隔离开来

  • 相关阅读:
    自适应Simpson积分
    斜率优化
    ORM的单表增删改查
    MTV模型—urls和view
    迭代器与生成器
    s7day2学习记录
    s7day1学习记录
    AI车牌识别涉及哪些技术?它是如何改变行业的?
    技术分享:人脸识别究竟是如何完成的?
    TSINGEE青犀视频行人检测景区测试时视频流切换本地背景音乐无法播放问题优化
  • 原文地址:https://www.cnblogs.com/handsome1013/p/6182816.html
Copyright © 2011-2022 走看看