V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
hastyfish
V2EX  ›  问与答

关于 SpringMVC 的原型模式和单例模式

  •  
  •   hastyfish · 2019-05-21 12:46:01 +08:00 · 1458 次点击
    这是一个创建于 2016 天前的主题,其中的信息可能已经有所发展或是发生改变。

    单例模式是单对象多线程,但会有并发问题 原型模式是浅复制多个对象给每个用户,不会有并发问题 如果是个中小型项目,在没有并发问题的地方用单例模式,有并发问题的地方用原型模式 这样理解对吗?

    10 条回复    2019-05-21 16:24:18 +08:00
    micean
        1
    micean  
       2019-05-21 13:02:59 +08:00
    线程安全不分项目大小
    单例有没有并发问题取决于你怎么取用
    设计模式是用来解决问题,不是产生问题
    hastyfish
        2
    hastyfish  
    OP
       2019-05-21 13:08:05 +08:00 via Android
    @micean
    我的意思是解决线程安全问题是单例模式下加锁还是直接用原型模式难道不是根据项目大小吗
    wolfie
        3
    wolfie  
       2019-05-21 13:14:27 +08:00
    @hastyfish #2
    Struts 使用成员变量接收参数,不能使用单例。
    SpringMVC 对应的请求是一个方法。
    hastyfish
        4
    hastyfish  
    OP
       2019-05-21 13:19:22 +08:00 via Android
    @wolfie
    我没有说接受参数问题。。。
    micean
        5
    micean  
       2019-05-21 14:05:28 +08:00
    @hastyfish
    加锁和实例化哪个性能损耗高也要看具体情况
    自己做一遍测试根据结果选择哪种方式
    passerbytiny
        6
    passerbytiny  
       2019-05-21 14:40:47 +08:00
    谁告诉你单例模式是单对象多线程的,谁告诉你原型模式是复制对象的,又是谁告诉你 Spring Bean 的作用范围是跟并发有关系的,净干些误人子弟的事。

    单例模式是设计模式的一种,当一个类,不管有多少个对象,你都可以把他看成一个对象的时候,为了性能上的考虑,可以采用单例模式。用之后更通俗的方式说,就是:无状态对象,采用单例模式。是否采用单例模式,仅取决于该类是否有状态,与多线程没有关系。严格的单例模式是要求全局都最多只有一个对象的(此时对象是允许有全局状态的),但实际上很难做到这样,Spring 的单例模式是每个容器一个对象,并不是全局一个。

    虽然 Spring 可能使用的浅复制去生成原型范围(请注意是范围不是模式)的 Bean 的新实例,但那只是技术实现或性能手段,在逻辑上,那就是个 new 了一个新对象。原型与新的 Bean 实例的关系,是类与对象的关系,不是对象与克隆的关系。

    无状态 Bean 用默认的单例模式,有状态 Bean 用原型模式,跟线程、并发没关系。另外,Spring Bean 不管是有状态还是无状态,通常主体都是服务而不是数据,是线程本身而不是线程要处理的共享数据。
    hastyfish
        7
    hastyfish  
    OP
       2019-05-21 15:15:17 +08:00 via Android
    @passerbytiny
    我的意思是 springMVC 中那个控制器选用单例模式还是原型模式。
    想想 servlet 就是创建一个 servlet 对象,对于每一个用户都开启一个线程,我只的单例多线程是这个意思
    hastyfish
        8
    hastyfish  
    OP
       2019-05-21 15:19:58 +08:00 via Android
    @passerbytiny
    spring bean 主要是为了 IoC 这肯定和并发没关
    passerbytiny
        9
    passerbytiny  
       2019-05-21 15:48:47 +08:00   ❤️ 1
    @hastyfish #7 控制器仍然是 Bean,唯一特殊的地方就是他通常是一个有状态 Bean,默认非单例,至于是 prototype 还是 request,我不太清楚。你的 servlet 线程模式已经是老黄历了,现在是 nio,不是 线程。
    hastyfish
        10
    hastyfish  
    OP
       2019-05-21 16:24:18 +08:00 via Android
    @passerbytiny
    今天算是体验到了什么叫听君一句话,胜读十年书
    老师在讲 JSP,我以为我已经跟上时代了,原来还差得远了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3492 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 11:03 · PVG 19:03 · LAX 03:03 · JFK 06:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.